Первое использование git remote update
, чтобы обновить ваши удаленные ссылки.Затем вы можете сделать одну из нескольких вещей, например:
git status -uno
, чтобы сообщить вам, находится ли отслеживаемая вами ветвь впереди, позади или отклонилась.Если он ничего не говорит, локальный и удаленный совпадают.
git show-branch *master
покажет вам фиксации во всех ветвях, имена которых заканчиваются на «master» (например, master и origin / master ).
Если вы используете -v
с git remote update
(git remote -v update
), вы можете увидеть, какие ветви были обновлены, поэтому вам больше не нужны никакие дальнейшие команды.
Однако похоже, что вы хотите сделать это в скрипте или программе и получить значение true / false.Если да, есть способы проверить взаимосвязь между вашим текущим коммитом HEAD и заголовком отслеживаемой ветви, хотя, поскольку есть четыре возможных результата, вы не можете уменьшить их до да / нетответ.Тем не менее, если вы готовы сделать pull --rebase
, то вы можете рассматривать «местный позади» и «местный разошелся» как «нужно тянуть», а два других - как «не нужно тянуть».
Вы можете получить идентификатор коммита для любой ссылки, используя git rev-parse <ref>
, поэтому вы можете сделать это для master и origin / master и сравнить их.Если они равны, ветви одинаковы.Если они неравны, вы хотите знать, что впереди другого.Использование git merge-base master origin/master
покажет вам общего предка обеих ветвей, и если они не разошлись, это будет то же самое, что и та или другая.Если вы получаете три разных идентификатора, ветви разошлись.
Чтобы сделать это правильно, например, в скрипте, вы должны иметь возможность ссылаться на текущую ветку и отслеживаемую удаленную ветку.Функция настройки приглашения bash в /etc/bash_completion.d
имеет некоторый полезный код для получения имен веток.Тем не менее, вам, вероятно, не нужно получать имена.В Git есть несколько удобных сокращений для ссылок на ветки и коммиты (как описано в git rev-parse --help
).В частности, вы можете использовать @
для текущей ветви (при условии, что вы не находитесь в состоянии отсоединенной головки) и @{u}
для его восходящей ветви (например, origin/master
).Таким образом, git merge-base @ @{u}
вернет коммит (хеш), при котором текущая ветвь и его восходящий поток расходятся, а git rev-parse @
и git rev-parse @{u}
дадут вам хэши двух подсказок.Это можно обобщить в следующем сценарии:
#!/bin/sh
UPSTREAM=${1:-'@{u}'}
LOCAL=$(git rev-parse @)
REMOTE=$(git rev-parse "$UPSTREAM")
BASE=$(git merge-base @ "$UPSTREAM")
if [ $LOCAL = $REMOTE ]; then
echo "Up-to-date"
elif [ $LOCAL = $BASE ]; then
echo "Need to pull"
elif [ $REMOTE = $BASE ]; then
echo "Need to push"
else
echo "Diverged"
fi
Примечание: более старые версии git не допускали @
сами по себе, поэтому вам, возможно, придется использовать @{0}
вместо этого.
Строка UPSTREAM=${1:-'@{u}'}
позволяет при желании явно передать ветвь восходящего потока на случай, если вы захотите проверить другую удаленную ветвь, отличную от настроенной для текущей ветки.Как правило, это будет иметь вид remotename / branchname .Если параметр не указан, по умолчанию используется значение @{u}
.
. Сценарий предполагает, что вы сначала выполнили git fetch
или git remote update
, чтобы обновлять ветви отслеживания.Я не встроил это в сценарий, потому что он более гибок, чтобы можно было выполнять выборку и сравнение как отдельные операции, например, если вы хотите сравнить без выборки, потому что вы уже загрузили недавно.