Что делает `git pull -all` на самом деле? [Дубликат]

json не может быть лучшим выбором для форматов на диске; Проблема, связанная с добавлением данных, является хорошим примером того, почему это может быть. В частности, объекты json имеют синтаксис, который означает, что весь объект должен быть прочитан и проанализирован, чтобы понять любую его часть.

К счастью, есть много других вариантов. Особенно простой - CSV; который хорошо поддерживается стандартной библиотекой python. Самым большим недостатком является то, что он хорошо работает только для текста; он требует дополнительных действий со стороны программиста для преобразования значений в числа или другие форматы, если это необходимо.

Другой вариант, который не имеет этого ограничения, заключается в использовании базы данных sqlite, которая также имеет встроенную базу данных, в поддержке в python. Это, вероятно, будет большим отступлением от кода, который у вас уже есть, но он более естественно поддерживает модель «изменить немного», которую вы, по-видимому, пытаетесь построить.

393
задан James Wierzba 15 June 2017 в 23:39
поделиться

20 ответов

Поведение, которое вы описываете для pull --all, точно так, как ожидалось, хотя и не обязательно полезно. Опция передается по git fetch, которая затем извлекает все ссылки из всех пультов, а не только необходимые; pull затем объединяет (или в вашем случае, переустанавливает) соответствующую отдельную ветвь.

Если вы хотите проверить другие ветви, вам придется проверить их. И да, для слияния (и rebasing) абсолютно требуется дерево работы, поэтому они не могут быть выполнены без проверки других ветвей. Вы можете завершить свои описанные шаги в сценарий / псевдоним, если хотите, хотя я бы предложил присоединиться к командам с &&, чтобы один из них потерпел неудачу, он не будет пытаться вспахивать.

144
ответ дан Cascabel 15 August 2018 в 23:22
поделиться
  • 1
    Если вы укажете пример командной строки, я бы проголосовал. У меня есть эта проблема на github. Я создал ветвь в пользовательском интерфейсе. Теперь мне нужно, чтобы мой локал показывал ветку. git pull - all; git branch ... argh ... команда: git branch -a – mariotti 29 October 2016 в 20:17
  • 2
    @mariotti Зависит от того, что вы пытаетесь сделать, и это не совсем ясно из вашего комментария. Возможно, вам лучше задать новый вопрос. – Cascabel 29 October 2016 в 21:46
  • 3
    Или @Jefromi .. привести пример. Я действительно согласился с тобой. – mariotti 3 November 2016 в 00:47
  • 4
    @mariotti. Цель этого ответа состоит в том, что встроенные команды фактически не выполняют то, что запросили ОП, поэтому необходимо выполнить последовательность шагов. Можно автоматизировать эти шаги (см., Например, ответ Джона), но они должны быть выполнены. Поэтому, если вы пытаетесь сделать это точно так же, как OP, на самом деле нет примера, и если вы пытаетесь сделать что-то другое, тогда вы должны задать новый вопрос - так работает StackOverflow! (И ваш комментарий неясно, но я думаю, что вы хотите что-то отличное от OP здесь, так что да, новый вопрос.) – Cascabel 3 November 2016 в 00:58
  • 5
    Да, немного что-то другое. Но ваш ответ был просто идеален для контекста. И мне, возможно, не нужно больше спрашивать только из-за вашего ответа. Just: принятый ответ использует git-up, который является просто интерфейсом для командной строки git (я полагаю). Я надеялся, что вы можете сделать это явным в нескольких строках команд git. Текущий ответ НЕ git. – mariotti 3 November 2016 в 01:21

Эта проблема еще не решена (по крайней мере), по крайней мере, нелегко / без скриптов: см. этот пост в списке рассылки git от Junio ​​C Hamano, объясняя ситуацию и предоставляя вызов для простого решения.

Основная причина состоит в том, что вам не нужно это:

С git, который не является древним (т.е. v1.5.0 или новее), нет причин иметь локальные " dev ", которые полностью отслеживают дистанцию. Если вы хотите только посмотреть и посмотреть, вы можете проверить ветвь удаленного отслеживания непосредственно на отдельном HEAD с помощью «git checkout origin/dev».

Это означает, что единственные случаи, которые нам нужно сделать удобно для пользователей обрабатывать эти локальные ветви, которые «отслеживают» удаленные, когда у вас есть локальные изменения, или когда вы планируете их использовать.

Если у вас есть локальные изменения на «dev», которые отмеченный для отслеживания удаления «dev», и если вы находитесь на ветке, отличной от «dev», тогда мы ничего не должны делать после того, как «git fetch» обновит «dev» удаленного отслеживания. В любом случае он не будет ускоренным переадресацией

. Призыв к решению заключался в том, что для опции или внешнего скрипта необходимо обрезать локальные ветви, которые следуют за ветками удаленного отслеживания, а не поддерживать их до -date путем быстрой пересылки, как и запрошенный оригинальный плакат.

Итак, как насчет «git branch --prune --remote=<upstream>», который итерации по локальным ветвям, и если

(1) а не текущая ветвь; и (2) он отмечен для отслеживания некоторой ветви, взятой из & lt; upstream & gt ;; и (3) он не имеет никаких коммитов по своему усмотрению;

затем удаляет эту ветвь? «git remote --prune-local-forks <upstream>» также прекрасен; Меня не волнует, какая команда очень сильно реализует эту функцию.

Примечание: с git 2.10 такого решения не существует. Обратите внимание, что подкоманда git remote prune и git fetch --prune относятся к удалению ветви удаленного отслеживания для ветки, которая больше не существует на удаленном компьютере, а не об удалении локальной ветви, которая отслеживает ветку удаленного отслеживания (для которой ветвь удаленного отслеживания является ветвью вверх по течению) .

10
ответ дан 3 revs 15 August 2018 в 23:22
поделиться
  • 1
    Вместо того, чтобы размещать ссылки, пожалуйста, публикуйте фактический контент, используя ссылки в качестве ссылок. Эта связь теперь мертва. Слишком плохо, звучало многообещающе. (Я понимаю, что этот ответ был с 2009 года, так что это всего лишь примечание для будущей справки.) – michael 27 January 2017 в 14:24
  • 2
    @michael_n: обновленный URL-адрес на данный момент, будет расширяться позже – Jakub Narębski 27 January 2017 в 14:33
  • 3
    спасибо (и ничего себе, быстрый ответ после стольких лет). Теперь я вижу, что этот поток является « вызовом для простого решения». в отличие от моего первоначального неправильного считывания, обеспечивает простое решение ". – michael 27 January 2017 в 14:42
  • 4
    @michael_n: расширен ... hmm, теперь я вижу, что сообщение не было точно о запрошенном решении, но речь шла о проблеме (предполагая случайный случай XY). – Jakub Narębski 27 January 2017 в 23:07
  • 5
    Хм, подглядывание с отсоединенной головкой должно быть проще, особенно оно должно показывать полезную информацию. В статусе и alllow для быстрой перемотки рабочей области с некоторой обратной связью (например, затянутыми фиксациями). Тогда это будет замена только для чтения локальных ветвей. – eckes 15 June 2017 в 23:50

Просто отправьте обновленный ответ. git-up больше не поддерживается, и если вы читаете документацию, они упоминают, что функциональность теперь доступна в git .

Начиная с Git 2.9, git pull - rebad -autostash делает в основном то же самое.

Соответственно, если вы обновляете Git 2.9 или новее, вы можете использовать этот псевдоним вместо установки git-up:

git config --global alias.up 'pull --rebase --autostash'

Вы также можете установить это для каждого git pull по Git 2.9 (спасибо @VonC, см. его ответ здесь )

git config --global pull.rebase true
git config --global rebase.autoStash true
3
ответ дан aug 15 August 2018 в 23:22
поделиться
  • 1
    Вам не нужен псевдоним. Простое git pull достаточно, с правильной конфигурацией: stackoverflow.com/a/40067353/6309 – VonC 5 September 2017 в 20:25
  • 2
    Большое спасибо, спасибо @VonC Я обновил свой ответ :) также мог бы подать PR в документацию git-up, потому что они не упоминают, что – aug 5 September 2017 в 21:03
  • 3
    Это не обновляет сразу все локальные ветви, поэтому я в основном использовал git-up. – ray 2 November 2017 в 20:40
  • 4
    Документация обновлена ​​в git-up :) – aug 8 November 2017 в 00:12

Чтобы ответить на этот вопрос Мэттом Коннолли, это более безопасный способ обновить локальные ссылки, которые можно быстро перенаправить, не проверяя ветвь. Он не обновляет ветви, которые не могут быть быстро перенаправлены (т. Е. Расходились), и не обновляет ветвь, которая в настоящее время проверена (потому что тогда рабочая копия также должна быть обновлена).

git fetch

head="$(git symbolic-ref HEAD)"
git for-each-ref --format="%(refname) %(upstream)" refs/heads | while read ref up; do
    if [ -n "$up" -a "$ref" != "$head" ]; then
        mine="$(git rev-parse "$ref")"
        theirs="$(git rev-parse "$up")"
        base="$(git merge-base "$ref" "$up")"
        if [ "$mine" != "$theirs" -a "$mine" == "$base" ]; then
            git update-ref "$ref" "$theirs"
        fi
    fi
done
1
ответ дан Bruno De Fraine 15 August 2018 в 23:22
поделиться

Вот хороший ответ: Как получить все ветви git

for remote in `git branch -r`; do git branch --track $remote; done
git pull --all
7
ответ дан Community 15 August 2018 в 23:22
поделиться
  • 1
    Почему вы предлагаете делать git fetch и git pull, а не просто git pull? – syntagma 20 August 2015 в 14:15
  • 2
    Благодарю. Кажется, что pull извлекает все ветки из всех пультов. Изменено – milkovsky 6 September 2015 в 09:23
  • 3
    Это приведет к удалению всех пультов, но только слияние текущей ветви. Если у вас 10 пультов, вам необходимо вручную проверить каждый из них и слить. – mpoisot 5 December 2016 в 19:51
  • 4
    Это позволит создать локальные удаленные ветви с префиксом origin/ – Yassine El Badaoui 17 October 2017 в 09:42

Это не так сложно автоматизировать:

#!/bin/sh
# Usage: fetchall.sh branch ...

set -x
git fetch --all
for branch in "$@"; do
    git checkout "$branch"      || exit 1
    git rebase "origin/$branch" || exit 1
done
24
ответ дан Fred Foo 15 August 2018 в 23:22
поделиться
  • 1
    Вероятно, лучше не использовать псевдонимы в сценариях. Это также ничего не приносит, просто переустанавливает на уже набранный контент. Вы должны изменить git rebase origin/$branch на git pull, чтобы он извлекался из соответствующей ветви отслеживания (предположительно по началу) и слияния или переустановки, как определено конфигурацией. – Cascabel 30 November 2010 в 22:06
  • 2
    @Jefromi: Я забыл fetch. Редактировал; дополнительные функции / исправления независимо от OP. – Fred Foo 30 November 2010 в 23:18
  • 3
    Я все еще думаю, что вы можете использовать pull (или проверить branch.<branch>.rebase), чтобы вы случайно не переустанавливали ветвь, которая настроена на нормальное выключение (слияние). – Cascabel 30 November 2010 в 23:54
  • 4
    @Jefromi вы можете отредактировать ответ соответственно? – Alexander Suraphel 7 April 2014 в 07:19
  • 5
    Попытайтесь использовать set -e вместо || exit 1, чтобы сделать вывод интерпретатора первой ошибкой. – crishoj 2 May 2018 в 11:32

Если refs / heads / master может быть быстро перенаправлен на refs / remotes / foo / master, вывод

git merge-base refs/heads/master refs/remotes/foo/master

должен вернуть идентификатор SHA1, который ссылается на / heads / master points. С этим вы можете собрать скрипт, который автоматически обновляет все локальные ветви, у которых не было никаких отвлекающих коммитов.

Этот маленький скрипт оболочки (я назвал его git-can-ff) иллюстрирует, как он может

#!/bin/sh

set -x

usage() {
    echo "usage: $(basename $0) <from-ref> <to-ref>" >&2
    exit 2
}

[ $# -ne 2 ] && usage

FROM_REF=$1
TO_REF=$2

FROM_HASH=$(git show-ref --hash $FROM_REF)
TO_HASH=$(git show-ref --hash $TO_REF)
BASE_HASH=$(git merge-base $FROM_REF $TO_REF)

if [ "$BASE_HASH" = "$FROM_HASH" -o \
     "$BASE_HASH" = "$FROM_REF" ]; then
    exit 0
else
    exit 1
fi
2
ответ дан hillu 15 August 2018 в 23:22
поделиться
  • 1
    Страница пользователя для git-merge-base предполагает, что это не для учеников Падуан ... – Norman Ramsey 9 March 2009 в 00:32
  • 2
    Что вы подразумеваете под этим комментарием? – hillu 9 March 2009 в 08:37
  • 3
    Я сам не умею писать сценарий, который предлагает холм, и я недостаточно уверен в своих знаниях git для использования git-merge-base. – Norman Ramsey 10 March 2009 в 03:43
  • 4
    Боюсь, я недостаточно разбираюсь в модели, чтобы использовать сценарий так любезно предоставлен. Этого достаточно, чтобы заставить человека хотеть переключиться на mercurcial. – Norman Ramsey 22 March 2009 в 04:45
  • 5
    Я лично нашел статью Томи Виртанена «Git для компьютерных ученых». весьма полезно ознакомиться с моделью и терминологией git. – hillu 22 March 2009 в 16:13

Я использую подкоманду sync hub для автоматизации этого. Хаб псевдонимов как git, поэтому введите команду:

git sync

Это обновляет все локальные ветви, имеющие соответствующую ветку вверх по течению. На странице man:

  • Если локальная ветка устарела, перетащите ее вперед,
  • Если локальная ветка содержит непроверенную работу, предупредите об этом; / g4]
  • Если ветка кажется объединенной, и ее ветвь восходящего потока была удалена, удалите ее.

Он также обрабатывает фиксированные / неработающие незафиксированные изменения в текущей ветке.

Я использовал подобный инструмент под названием git-up , но он больше не поддерживается, а git sync выполняет почти то же самое.

180
ответ дан John 15 August 2018 в 23:22
поделиться
  • 1
    Что относительно Windows? – Violet Giraffe 28 March 2015 в 15:23
  • 2
    Представленная здесь концепция перезагрузки не рекомендуется. У меня недостаточно очков для голосования, но в принципе очень плохая идея. Rebasing полностью испортит порядок ваших коммитов, и если вы делаете какой-либо анализ истории, вы будете путаться. Существует причина, по которой поведение git по умолчанию заключается в слиянии во время pull. – Trenton D. Adams 29 May 2015 в 19:31
  • 3
    Чтобы отключить автоматическое перезаключение git-up, запустите git config --global git-up.rebase.auto false. – Dan Loewenherz 16 July 2015 в 21:41
  • 4
    @MaxYankov. Сбрасывать общую историю, как правило, следует избегать, нет ничего плохого в том, чтобы сбрасывать локальные коммиты во время pull. – Dev 18 July 2015 в 17:33
  • 5
    Восстановление местных коммитов переписывает историю и делает ее более простой, чем она есть на самом деле. С rebase вы можете найти себя с кодом, который автоматически объединяется, но не компилируется или, что еще хуже, компилируется, но не работает. Объединение подтверждает то, как вы работали: вы внесли изменения и протестировали их перед тем, как включить изменения других людей, а слияние фиксации - очень полезный момент: это место, где вы убедитесь, что разные шагеты хорошо сочетаются друг с другом. Rebasing делает его похожим на то, что этот процесс никогда не происходит, что просто неверно и является очень опасной практикой. – Max Yankov 19 July 2015 в 11:25

Это все еще не автоматическое, так как я хочу, чтобы была опция - и должна быть какая-то проверка, чтобы убедиться, что это может произойти только для быстрых обновлений (поэтому вручную делать притяжение намного безопаснее! !), но предостережения в стороне вы можете:

git fetch origin
git update-ref refs/heads/other-branch origin/other-branch

обновить позицию вашего локального отделения, не проверяя его.

Примечание: вы потеряете свою текущую ветку положение и перемещение его туда, где находится ветвь происхождения, а это означает, что если вам нужно слить, вы потеряете данные!

14
ответ дан Matt Connolly 15 August 2018 в 23:22
поделиться
  • 1
    Это именно то решение, которое я искал. Обычно я не делаю никаких изменений в нескольких ветвях и просто хочу обновить различные локальные ветви, чтобы они соответствовали удаленным. Это решение намного приятнее, чем мой обычный метод удаления / повторной проверки! – Dave Knight 13 June 2015 в 20:32

Здесь есть много приемлемых ответов, но некоторые из сантехники могут быть немного непрозрачными для непосвященных. Вот еще более простой пример, который можно легко настроить:

$ cat ~/bin/git/git-update-all
#!/bin/bash
# Update all local branches, checking out each branch in succession.
# Eventually returns to the original branch. Use "-n" for dry-run.
git_update_all() {
  local run br
  br=$(git name-rev --name-only HEAD 2>/dev/null)
  [ "$1" = "-n" ] && shift && run=echo

  for x in $( git branch | cut -c3- ) ; do
     $run git checkout $x && $run git pull --ff-only || return 2
  done

  [ ${#br} -gt 0 ] && $run git checkout "$br"
}

git_update_all "$@"

Если вы добавите ~/bin/git в свой PATH (при условии, что файл ~/bin/git/git-update-all), вы можете просто запустить:

$ git update-all
7
ответ дан michael 15 August 2018 в 23:22
поделиться

Добавьте этот скрипт в .profile в Mac OS X:

# Usage:
#   `git-pull-all` to pull all your local branches from origin
#   `git-pull-all remote` to pull all your local branches from a named remote

function git-pull-all() {
    START=$(git symbolic-ref --short -q HEAD);
    for branch in $(git branch | sed 's/^.//'); do
        git checkout $branch;
        git pull ${1:-origin} $branch || break;
    done;
    git checkout $START;
};

function git-push-all() {
    git push --all ${1:-origin};
};
4
ответ дан Mike 15 August 2018 в 23:22
поделиться
  • 1
    Разве это не должно сначала сбрасывать все изменения, а затем восстанавливать их? – Mel 4 February 2016 в 18:20

Примечание. Несмотря на то, что я разместил собственное решение, я бы рекомендовал использовать git-up , что также является принятым ответом.


Я знаю, что этот вопрос почти 3 года, но я задал себе тот же вопрос и не нашел готового решения. Итак, я создал собственный скрипт командной оболочки git.

Здесь он идет, скрипт git-ffwd-update делает следующее ...

  1. он выдает git remote update, чтобы получить значения lates revs
  2. , затем использует git remote show, чтобы получить список локальных ветвей, отслеживающих удаленную ветвь (например, ветви, которые могут использоваться с git pull)
  3. , затем он проверяет с помощью git rev-list --count <REMOTE_BRANCH>..<LOCAL_BRANCH>, сколько из них фиксирует локальную ветвь за пультом (и наоборот наоборот)
  4. , если локальная ветвь 1 или более совершает движение вперед, она НЕ может быть переадресована и должна быть объединены или переустановлены вручную
  5. , если локальная ветвь равна 0, и вперед 1 и более, она может быть быстро переадресована git branch -l -f <LOCAL_BRANCH> -t <REMOTE_BRANCH>

скрипт можно вызвать как:

$ git ffwd-update
Fetching origin
 branch bigcouch was 10 commit(s) behind of origin/bigcouch. reseting local branch to remote
 branch develop was 3 commit(s) behind of origin/develop. reseting local branch to remote
 branch master is 6 commit(s) behind and 1 commit(s) ahead of origin/master. could not be fast-forwarded

Полный скрипт должен быть сохранен как git-ffwd-update и должен находиться на PATH.

#!/bin/bash

main() {
  REMOTES="$@";
  if [ -z "$REMOTES" ]; then
    REMOTES=$(git remote);
  fi
  REMOTES=$(echo "$REMOTES" | xargs -n1 echo)
  CLB=$(git branch -l|awk '/^\*/{print $2}');
  echo "$REMOTES" | while read REMOTE; do
    git remote update $REMOTE
    git remote show $REMOTE -n \
    | awk '/merges with remote/{print $5" "$1}' \
    | while read line; do
      RB=$(echo "$line"|cut -f1 -d" ");
      ARB="refs/remotes/$REMOTE/$RB";
      LB=$(echo "$line"|cut -f2 -d" ");
      ALB="refs/heads/$LB";
      NBEHIND=$(( $(git rev-list --count $ALB..$ARB 2>/dev/null) +0));
      NAHEAD=$(( $(git rev-list --count $ARB..$ALB 2>/dev/null) +0));
      if [ "$NBEHIND" -gt 0 ]; then
        if [ "$NAHEAD" -gt 0 ]; then
          echo " branch $LB is $NBEHIND commit(s) behind and $NAHEAD commit(s) ahead of $REMOTE/$RB. could not be fast-forwarded";
        elif [ "$LB" = "$CLB" ]; then
          echo " branch $LB was $NBEHIND commit(s) behind of $REMOTE/$RB. fast-forward merge";
          git merge -q $ARB;
        else
          echo " branch $LB was $NBEHIND commit(s) behind of $REMOTE/$RB. reseting local branch to remote";
          git branch -l -f $LB -t $ARB >/dev/null;
        fi
      fi
    done
  done
}

main $@
33
ответ дан muhqu 15 August 2018 в 23:22
поделиться
  • 1
    Спасибо за этот скрипт. Возможно ли, что кто-то может преобразовать этот скрипт в пакет Windows? – Saariko 2 August 2012 в 11:35
  • 2
    @Saariko, почему вы не хотите использовать git на обычной оболочке Windows? Если вы используете что-то вроде cygwin, этот скрипт должен работать нормально ... (хотя я его не тестировал) – muhqu 3 August 2012 в 07:05
  • 3
    @RyanWilcox спасибо, я использую его, как каждый (рабочий) день ... ;-), возможно, вам захочется взглянуть на мои точечные файлы для более связанных с git скриптов и псевдонимов: github.com/muhqu / точечные файлы – muhqu 25 February 2014 в 11:17
  • 4
    Отлично подходит для окон, спасибо muhqu – Javaboy 23 July 2014 в 17:39
  • 5
    @muhqu Я пытаюсь использовать ваш скрипт, и я не знаю, почему он работал в первый раз, но он не работает & quot; как ожидалось & quot; прямо сейчас. Например, посмотрите на этот . Почему мастер все еще удерживает 78 после того, как я запустил ваш скрипт? – BPL 3 November 2016 в 20:18

Начиная с git 2.9:

git pull --rebase --autostash

См. https://git-scm.com/docs/git-rebase

Автоматически создавать временный тайник перед началом операции и применять его после завершения операции. Это означает, что вы можете запустить rebase на грязной worktree. Тем не менее, используйте с осторожностью: окончательное приложение с приложением после успешной перезагрузки может привести к нетривиальным конфликтам.

-1
ответ дан nha 15 August 2018 в 23:22
поделиться

Сценарий, который я написал для моего GitBash . Выполняет следующее:

  • По умолчанию тянет из источника для всех ветвей, которые настроены для отслеживания начала координат, позволяет при желании указать другой пульт.
  • Если ваша текущая ветка находится в грязном состоянии, тогда он задерживает ваши изменения и попытается восстановить эти изменения в конце.
  • Для каждой локальной ветви, которая настроена для отслеживания удаленной ветки, будет: git checkout branch git pull origin
  • Наконец, вернем вас в исходное состояние ветви и восстановления.

** Я использую это, но не тестировал полностью, используйте на свой страх и риск. Пример этого скрипта в файле .bash_alias здесь .

    # Do a pull on all branches that are tracking a remote branches, will from origin by default.
    # If current branch is dirty, will stash changes and reply after pull.
    # Usage: pullall [remoteName]
    alias pullall=pullAll
    function pullAll (){
     # if -h then show help
     if [[ $1 == '-h' ]]
    then
      echo "Description: Pulls new changes from upstream on all branches that are tracking remotes."
      echo 
      echo "Usage: "
      echo "- Default: pullall"
      echo "- Specify upstream to pull from: pullall [upstreamName]"
      echo "- Help: pull-all -h"
    else

     # default remote to origin
     remote="origin"
     if [ $1 != "" ]
     then
       remote=$1
     fi

     # list all branches that are tracking remote
     # git branch -vv : list branches with their upstreams
     # grep origin : keep only items that have upstream of origin
     # sed "s/^.."... : remove leading *
     # sed "s/^"..... : remove leading white spaces
     # cut -d" "..... : cut on spaces, take first item
     # cut -d splits on space, -f1 grabs first item
     branches=($(git branch -vv | grep $remote | sed "s/^[ *]*//" | sed "s/^[ /t]*//" | cut -d" " -f1))

     # get starting branch name
     startingBranch=$(git rev-parse --abbrev-ref HEAD)

     # get starting stash size
     startingStashSize=$(git stash list | wc -l)

     echo "Saving starting branch state: $startingBranch"
     git stash

     # get the new stash size
     newStashSize=$(git stash list | wc -l)

     # for each branch in the array of remote tracking branches
     for branch in ${branches[*]}
     do
       echo "Switching to $branch"
       git checkout $branch

       echo "Pulling $remote"
       git pull $remote

     done

     echo "Switching back to $startingBranch"
     git checkout $startingBranch

     # compare before and after stash size to see if anything was stashed
     if [ "$startingStashSize" -lt "$newStashSize" ]
     then
       echo "Restoring branch state"
       git stash pop
     fi
    fi
    }
3
ответ дан philosowaffle 15 August 2018 в 23:22
поделиться
  • 1
    Можете ли вы предоставить эквивалентный файл летучей мыши Windows? – Jaffy 16 July 2015 в 07:09
  • 2
    @Jaffy Не уверен, сколько времени у меня на руках, и я не супер бегло в партии, но я могу уйти. Я опубликую свой прогресс здесь , может быть, другие могут вмешаться и помочь? – philosowaffle 16 July 2015 в 13:27

Здесь много ответов, но никто не использует git-fetch для непосредственного обновления локального рефлекса, что намного проще, чем проверка ветвей, и более безопасная, чем git-update-ref.

Здесь мы используйте git-fetch для обновления не текущих ветвей и git pull --ff-only для текущей ветви. Это:

  • Не требует проверки ветвей
  • Обновляет ветви только в том случае, если они могут быть быстро переадресованы
  • Будет сообщать, когда он не может fast-forward

, и вот он:

#!/bin/bash
currentbranchref="$(git symbolic-ref HEAD 2>&-)"
git branch -r | grep -v ' -> ' | while read remotebranch
do
    # Split <remote>/<branch> into remote and branchref parts
    remote="${remotebranch%%/*}"
    branchref="refs/heads/${remotebranch#*/}"

    if [ "$branchref" == "$currentbranchref" ]
    then
        echo "Updating current branch $branchref from $remote..."
        git pull --ff-only
    else
        echo "Updating non-current ref $branchref from $remote..."
        git fetch "$remote" "$branchref:$branchref"
    fi
done

Из справочной страницы для git-fetch:

   <refspec>
       The format of a <refspec> parameter is an optional plus +, followed by the source ref <src>,
       followed by a colon :, followed by the destination ref <dst>.

       The remote ref that matches <src> is fetched, and if <dst> is not empty string, the local ref
       that matches it is fast-forwarded using <src>. If the optional plus + is used, the local ref is
       updated even if it does not result in a fast-forward update.

Указывая git fetch <remote> <ref>:<ref> (без каких-либо +), мы получаем выборку, которая обновляет локальный рефер, только когда его можно быстро пересылать.

Примечание: это предполагает, что локальная и удаленная ветви называются одинаковыми (и что вы хотите отслеживать все ветви), он должен действительно использовать информацию о том, какие локальные филиалы у вас есть и что они настроены для отслеживания.

7
ответ дан quornian 15 August 2018 в 23:22
поделиться
  • 1
    "Обновляет ветви только в том случае, если они могут быть быстро перенаправлены & quot; - в чем смысл быстрой перемотки вперед? Если мне нужны последние источники во всех моих филиалах, то почему я должен заботиться о быстрой пересылке или нет? Подобные вещи заставляют меня смеяться над Гит и его Фанбои. Вы не можете сделать это только одной командой. Вместо этого вам нужно выполнить шаги c*n (вместо 1), где c - некоторое количество повторяющихся команд, а n - количество ветвей. – jww 21 May 2016 в 01:04
  • 2
    @jww Это не помогает «рассмеяться над Гит и его Фанбои». [sic], когда используется VCS в большинстве стран мира. Но я отвлекся ... Я думаю, что в контексте такого типа «глобального тянуть», скрипт разумно не пытаться вносить изменения в недействующие ветви, если они имеют конфликты слияния. – Ville 13 November 2017 в 20:52
  • 3
    Это было полезно, спасибо. Единственное, что мне не понравилось, это то, что он создал ветвь локально для каждой удаленной ветви (включая те, в которых меня это не интересует), поэтому я изменил git branch -r | grep -v ' -> ' | while read remotebranch на git branch -r | grep -v ' -> ' | grep -f <(git branch | cut -c 3- | awk '{print "\\S*/"$0"$"}') | while read remotebranch, чтобы ограничить ее ветвями, которые у меня уже есть локально. Также я добавил git fetch --prune в начале, чтобы обновить список удаленных филиалов, прежде чем что-либо делать, что позволяет избежать некоторых предупреждений. – Nate Cook 19 March 2018 в 20:17

Немного другой скрипт, который только быстрые переходы, имена которых совпадают с их ветвью вверх по течению. Он также обновляет текущую ветвь, если возможна быстрая перемотка вперед.

Убедитесь, что все ветви ветвей ваших ветвей установлены правильно, запустив git branch -vv. Установите верхнюю ветвь с помощью git branch -u origin/yourbanchname

Скопируйте пасту в файл и chmod 755:

#!/bin/sh

curbranch=$(git rev-parse --abbrev-ref HEAD)

for branch in $(git for-each-ref refs/heads --format="%(refname:short)"); do
        upbranch=$(git config --get branch.$branch.merge | sed 's:refs/heads/::');
        if [ "$branch" = "$upbranch" ]; then
                if [ "$branch" = "$curbranch" ]; then
                        echo Fast forwarding current branch $curbranch
                        git merge --ff-only origin/$upbranch
                else
                        echo Fast forwarding $branch with origin/$upbranch
                        git fetch . origin/$upbranch:$branch
                fi
        fi
done;
0
ответ дан qwertzguy 15 August 2018 в 23:22
поделиться

Сценарий из @larsmans немного улучшился:

#!/bin/sh

set -x
CURRENT=`git rev-parse --abbrev-ref HEAD`
git fetch --all
for branch in "$@"; do
  if ["$branch" -ne "$CURRENT"]; then
    git checkout "$branch" || exit 1
    git rebase "origin/$branch" || exit 1
  fi
done
git checkout "$CURRENT" || exit 1
git rebase "origin/$CURRENT" || exit 1

После завершения работы, рабочая копия удаляется из той же ветви, что и до вызова сценария.

Версия git pull:

#!/bin/sh

set -x
CURRENT=`git rev-parse --abbrev-ref HEAD`
git fetch --all
for branch in "$@"; do
  if ["$branch" -ne "$CURRENT"]; then
    git checkout "$branch" || exit 1
    git pull || exit 1
  fi
done
git checkout "$CURRENT" || exit 1
git pull || exit 1
1
ответ дан Saran 15 August 2018 в 23:22
поделиться

Если вы находитесь в Windows, вы можете использовать PyGitUp , который является клоном git-up для Python. Вы можете установить его с помощью pip с помощью pip install --user git-up или через Scoop , используя scoop install git-up

[4] [/g3]

3
ответ дан Simon Hartcher 15 August 2018 в 23:22
поделиться

Похоже, что многие другие внесли аналогичные решения, но я думал, что разделю то, что я придумал, и пригласить других вносить свой вклад. Это решение имеет приятный красочный выход, изящно обрабатывает ваш текущий рабочий каталог и быстро, потому что он не делает никаких проверок и оставляет ваш рабочий каталог в такт. Кроме того, это всего лишь сценарий оболочки без зависимостей, кроме git. (только проверено на OSX до сих пор)

#!/usr/bin/env bash

gitup(){    
RED='\033[33;31m'
YELLO='\033[33;33m'
GREEN='\033[33;32m'
NC='\033[0m' # No Color

HEAD=$(git rev-parse HEAD)
CHANGED=$(git status --porcelain | wc -l)

echo "Fetching..."
git fetch --all --prune &>/dev/null
for branch in `git for-each-ref --format='%(refname:short)' refs/heads`; do

    LOCAL=$(git rev-parse --quiet --verify $branch)
    if [ "$HEAD" = "$LOCAL" ] && [ $CHANGED -gt 0 ]; then
        echo -e "${YELLO}WORKING${NC}\t\t$branch"
    elif git rev-parse --verify --quiet $branch@{u}&>/dev/null; then
        REMOTE=$(git rev-parse --quiet --verify $branch@{u})
        BASE=$(git merge-base $branch $branch@{u})

        if [ "$LOCAL" = "$REMOTE" ]; then
           echo -e "${GREEN}OK${NC}\t\t$branch" 
        elif [ "$LOCAL" = "$BASE" ]; then
            if [ "$HEAD" = "$LOCAL" ]; then
                git merge $REMOTE&>/dev/null
            else
                git branch -f $branch $REMOTE
            fi
            echo -e "${GREEN}UPDATED${NC}\t\t$branch"
        elif [ "$REMOTE" = "$BASE" ]; then
            echo -e "${RED}AHEAD${NC}\t\t$branch"
        else
            echo -e "${RED}DIVERGED${NC}\t\t$branch"
        fi
    else
        echo -e "${RED}NO REMOTE${NC}\t$branch"
    fi
done
}

https://github.com/davestimpert/gitup

Извините, я тоже, похоже, пришел с тем же именем, что и другой инструмент выше.

1
ответ дан Stimp 15 August 2018 в 23:22
поделиться
  • 1
    Вы тот, кто написал это? Если это так, пожалуйста, сообщите о своей принадлежности, то есть сообщите нам, как вы к этому относитесь. Пожалуйста, читайте больше об этом для получения дополнительной информации. В частности, Не говорите - покажите! ; Расскажите, какие части вашего скрипта и как / почему он решает проблему. – Keale 15 October 2015 в 00:31
  • 2
    Да, я написал это. Я включил источник выше для быстрой скопирования в ваш .bashrc или .zshrc. – Stimp 16 October 2015 в 13:20
  • 3
    Это хорошее решение и работает хорошо. Никто не уведомил об этом? – Ville 13 November 2017 в 20:06

Это можно сделать, используя следующий скрипт ... Сначала он будет извлекать все ветви и проверку по одному и обновлять сам по себе.

#!/bin/bash
git branch -r | grep -v '\->' | while read remote; do git branch --track 
"${remote#origin/}" "$remote"; done

set -x
CURRENT=`git rev-parse --abbrev-ref HEAD`
git fetch --all
branch_name=$(git branch | awk '{print $1" "}' | grep -v '*' | xargs)
for branch in $branch_name; do
   git checkout "$branch" || exit 1
   git rebase "origin/$branch" || exit 1
   git pull origin $branch|| exit 1
done
git checkout "$CURRENT" || exit 1
git pull || exit 1
1
ответ дан Vikash Singh 15 August 2018 в 23:22
поделиться
  • 1
    Добавьте некоторое объяснение для подсчета ответа – fool-dev 16 January 2018 в 12:56
Другие вопросы по тегам:

Похожие вопросы: