Primeiro uso git remote update
, para atualizar seus árbitros remotos. Então você pode fazer uma de várias coisas, como:
git status -uno
dirá se o ramo que você está rastreando está à frente, atrás ou divergiu. Se não diz nada, o local e o remoto são os mesmos.
git show-branch *master
mostrará os commits em todos os ramos cujos nomes terminam em 'master' (por exemplo, master e origin / master ).
Se você usar -v
com git remote update
( git remote -v update
), poderá ver quais ramificações foram atualizadas, para que você realmente não precise de mais comandos.
No entanto, parece que você deseja fazer isso em um script ou programa e acabar com um valor verdadeiro / falso. Nesse caso, existem maneiras de verificar o relacionamento entre o commit HEAD atual e o chefe do ramo que você está rastreando, embora como haja quatro resultados possíveis, você não possa reduzi-lo a uma resposta sim / não. No entanto, se você estiver preparado para fazer um pull --rebase
procedimento, poderá tratar "o local está atrasado" e "o local está diferente" como "precisa puxar", e os outros dois como "não precisam puxar".
Você pode obter o ID de confirmação de qualquer ref usando git rev-parse <ref>
, para fazer isso para mestre e origem / mestre e compará-los. Se são iguais, os galhos são os mesmos. Se eles são desiguais, você quer saber o que está à frente do outro. Usar git merge-base master origin/master
indica o ancestral comum de ambos os ramos, e se eles não divergiram, será o mesmo que um ou outro. Se você obtiver três IDs diferentes, os ramos divergirão.
Para fazer isso corretamente, por exemplo, em um script, você deve poder se referir à ramificação atual e à ramificação remota que está rastreando. A função de configuração do prompt do bash /etc/bash_completion.d
possui algum código útil para obter nomes de ramificações. No entanto, você provavelmente não precisa obter os nomes. O Git possui algumas regras simples para se referir a ramificações e confirmações (conforme documentado em git rev-parse --help
). Em particular, você pode usar @
a ramificação atual (supondo que você não esteja em um estado de cabeça desanexada) e @{u}
a ramificação upstream (por exemplo origin/master
). Assim, git merge-base @ @{u}
irá retornar o (hash do) cometer pelo qual o ramo atual e seu divergem montante e git rev-parse @
e git rev-parse @{u}
lhe dará os hashes das duas pontas. Isso pode ser resumido no seguinte script:
#!/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
Nota: as versões mais antigas do git não eram permitidas @
por si só, então você pode ter que usá-lo @{0}
.
A linha UPSTREAM=${1:-'@{u}'}
permite que você passe opcionalmente uma ramificação upstream explicitamente, caso deseje verificar uma ramificação remota diferente daquela configurada para a ramificação atual. Isso normalmente seria no formato remotename / branchname . Se nenhum parâmetro for fornecido, o valor será padronizado como @{u}
.
O script pressupõe que você tenha feito um git fetch
ou git remote update
primeiro, para atualizar as ramificações de rastreamento. Não criei isso no script porque é mais flexível poder fazer a busca e a comparação como operações separadas, por exemplo, se você deseja comparar sem buscar porque já buscou recentemente.