763 votes

git : vérifier si un pull est nécessaire

Comment vérifier si le dépôt distant a été modifié et si je dois le retirer ?

Maintenant j'utilise ce simple script :

git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1

mais il est plutôt lourd.

Connaissez-vous un meilleur moyen ? La solution idéale serait de vérifier toutes les branches distantes, et de retourner les noms des branches modifiées et le nombre de nouveaux commits dans chacune d'elles.

1039voto

Neil Mayhew Points 2579

git remote update pour mettre à jour vos arbitres à distance. Ensuite, vous pouvez faire l'une des nombreuses choses suivantes :

  1. git status -uno vous indiquera si la branche que vous suivez est en avance, en retard ou a divergé. S'il ne dit rien, le local et le distant sont les mêmes.

  2. git show-branch *master vous montrera les commits dans toutes les branches dont le nom se termine par master (par exemple master et origin/master).

Si vous utilisez -v avec git remote update vous pouvez voir quelles branches ont été mises à jour, donc vous n'avez pas vraiment besoin d'autres commandes.

Cependant, il semble que vous vouliez faire cela dans un script ou un programme et vous retrouver avec une valeur vrai/faux. Si c'est le cas, il existe des moyens de vérifier la relation entre votre commit HEAD actuel et la tête de la branche que vous suivez, bien que, puisqu'il y a quatre résultats possibles, vous ne pouvez pas le réduire à une réponse oui/non. Cependant, si vous êtes prêt à faire un pull --rebase on peut alors considérer que " la section locale est en retard " et " la section locale a divergé " comme " il faut tirer ", et les deux autres comme " il ne faut pas tirer ".

Vous pouvez obtenir l'identifiant de commit de n'importe quelle référence en utilisant git rev-parse <ref> Vous pouvez donc effectuer cette opération pour master et origin/master et les comparer. S'ils sont égaux, les branches sont les mêmes. Si elles sont inégales, vous voulez savoir laquelle est en avance sur l'autre. Utilisation de git merge-base master origin/master vous indiquera l'ancêtre commun des deux branches, et si elles n'ont pas divergé, ce sera le même que l'une ou l'autre. Si vous obtenez trois identifiants différents, les branches ont divergé.

Pour faire cela correctement, par exemple dans un script, vous devez être en mesure de faire référence à la branche actuelle et à la branche distante qu'elle suit. La fonction bash prompt-setting dans /etc/bash_completion.d contient du code utile pour obtenir les noms des branches. Cependant, vous n'avez probablement pas besoin d'obtenir ces noms. Git dispose de quelques raccourcis pour se référer aux branches et aux commits (comme documenté dans le fichier git rev-parse --help ). En particulier, vous pouvez utiliser @ pour la branche actuelle (en supposant que vous n'êtes pas dans un état de tête détachée) et @{u} pour sa branche amont (par exemple origin/master ). Ainsi, git merge-base @ @{u} retournera le (hachage du) commit auquel la branche courante et son amont divergent et git rev-parse @ y git rev-parse @{u} vous donnera les hachages des deux conseils. Ceci peut être résumé dans le script suivant :

#!/bin/sh

LOCAL=$(git rev-parse @)
REMOTE=$(git rev-parse @{u})
BASE=$(git merge-base @ @{u})

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

151voto

Nocturne Points 9973

La façon la plus simple de procéder est

git fetch origin

# See if there are any incoming changes
git log HEAD..origin/master --oneline

(Je suppose que origin/master est votre branche de suivi à distance)

Si des commits sont listés dans la sortie ci-dessus, alors vous avez des changements entrants -- vous devez fusionner. Si aucun commits n'est listé par git log alors il n'y a rien à fusionner.

Notez que cela fonctionnera même si vous êtes sur une branche de fonctionnalité -- qui n'a pas de suivi à distance, puisque si fait explicitement référence à origin/master au lieu d'utiliser implicitement le branche amont se souvient de Git.

110voto

Stephen Haberman Points 103

Si c'est pour un script, vous pouvez utiliser :

$(git rev-parse HEAD) == $(git rev-parse @{u})

(Note : l'avantage de cette réponse par rapport aux réponses précédentes est que vous n'avez pas besoin d'une commande séparée pour obtenir le nom de la branche courante. "HEAD" et "@{u}" (l'amont de la branche courante) s'en occupent. Voir "git rev-parse --help" pour plus de détails).

49voto

wjordan Points 11

Voici un script Bash qui compare le hash HEAD commit de la branche courante à celui de la branche amont distante, sans lourdeur. git fetch o git pull --dry-run opérations nécessaires :

[ $(git rev-parse HEAD) = $(git ls-remote $(git rev-parse --abbrev-ref @{u} | \
sed 's/\// /g') | cut -f1) ] && echo up to date || echo not up to date

Voici comment se décompose cette ligne quelque peu dense :

  • Les commandes sont regroupées et imbriquées en utilisant $(x) Bash substitution de commande la syntaxe.
  • git rev-parse --abbrev-ref @{u} renvoie une réf. amont abrégée (par ex. origin/master ), qui est ensuite converti en champs séparés par des espaces par la fonction piped sed commande, par exemple origin master .
  • Cette chaîne est introduite dans git ls-remote qui renvoie le commit principal de la branche distante. Cette commande va communiquer avec le dépôt distant. Le piped cut extrait uniquement le premier champ (le hachage de la livraison), en supprimant la chaîne de référence séparée par des tabulations.
  • git rev-parse HEAD renvoie le hachage de la commande locale.
  • La syntaxe Bash [ a = b ] && x || y complète la phrase : c'est un Bash. comparaison de chaînes de caractères = dans le cadre d'une construction de test [ test ] suivi des constructions and-list et or-list. && true || false .

44voto

brool Points 1357

La commande

git ls-remote origin -h refs/heads/master

listera la tête actuelle sur le distant -- vous pouvez la comparer à une valeur précédente ou voir si vous avez le SHA dans votre repo local.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X