48 votes

git: savoir par programme de combien la branche est en avance / derrière une branche distante

J'aimerais extraire les informations imprimées après un git status, ce qui ressemble à:

# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.

Bien sûr, je peux analyser la sortie de l' git status mais ce n'est pas recommandé car cette lisibles par l'homme de sortie est susceptible de changer.

Il y a deux problèmes:

  1. Comment connaître le suivi à distance de la branche? Il est souvent origin/branch mais ne doit pas être.
  2. Comment obtenir les chiffres? Comment savoir si elle est en avance/en retard? Par combien de livraisons? Et que dire de la divergé de la branche cas?

23voto

jamessan Points 16420

git rev-list origin..HEAD affichera les commits qui se trouvent dans votre branche actuelle, mais pas l'origine - c'est-à-dire si vous êtes en avance sur l'origine et par quels commits.

git rev-list HEAD..origin montrera le contraire.

Si les deux commandes affichent des commits, vous avez des branches divergentes.

20voto

araqnid Points 33350

mise à jour

Comme l'a souligné amalloy, les dernières versions de git d'aide pour trouver la correspondance de suivi de la branche pour une branche donnée, en donnant "branchname@{en amont}" (ou "branchname@{u}", ou "@{u}" pour le suivi, la direction de). Effectivement cela remplace le script ci-dessous. Vous pouvez le faire:

git rev-list @{u}..
git rev-list --left-right --boundary @{u}...
gitk @{u}...

etc. Par exemple, j'ai git q alias git log --pretty='...' @{u}.. de me montrer en "file d'attente" s'engage prêt pour pousser.

réponse originale à cette question

Il ne semble pas être un moyen facile de trouver le suivi de la branche en général, sans l'analyse beaucoup plus de git config que ce qui est pratique dans quelques commandes shell. Mais pour de nombreux cas, cela ira un long chemin:

# work out the current branch name
currentbranch=$(expr $(git symbolic-ref HEAD) : 'refs/heads/\(.*\)')
[ -n "$currentbranch" ] || die "You don't seem to be on a branch"
# look up this branch in the configuration
remote=$(git config branch.$currentbranch.remote)
remote_ref=$(git config branch.$currentbranch.merge)
# convert the remote ref into the tracking ref... this is a hack
remote_branch=$(expr $remote_ref : 'refs/heads/\(.*\)')
tracking_branch=refs/remotes/$remote/$remote_branch
# now $tracking_branch should be the local ref tracking HEAD
git rev-list $tracking_branch..HEAD

L'autre, plus de force brute, de l'approche:

git rev-list HEAD --not --remotes

jamessan la réponse explique comment trouver les différences relatives entre $tracking_branch et la TÊTE à l'aide de git rev-list. Une chose amusante que vous pouvez faire:

git rev-list --left-right $tracking_branch...HEAD

(note de trois points entre $tracking_branch et de la TÊTE). Cela permettra de montrer s'engage sur les deux "bras" avec une marque de distinction à l'avant: "<" pour les livraisons sur $tracking_branch, et ">" pour les livraisons sur la TÊTE.

11voto

max Points 16106

Vous pouvez essayer git branch -v -v . Avec l'indicateur -v donné deux fois, il affiche les noms des branches en amont. Exemple de sortie:

 * devel  7a5ff2c [origin/devel: ahead 1] smaller file status overlay icons
  master 37ca389 [origin/master] initial project check-in.
 

Je pense que ce format est plus stable que la sortie git status .

7voto

scicalculator Points 350

Edit: Ma réponse n'était pas très bonne parce qu'elle reposait sur l'utilisateur de disposer d'une distance appelée "origine". Il a également omis si la branche courante a eu un suivi de branche en plus de l'origine de la tête. Ces défauts essentiellement inutile. Cependant, la réponse de @araqnid n'est pas la méthode la plus efficace et la façon dont il arrive à l' $tracking_branch est à moins de détroit vers l'avant. Le plus efficace (plus rapide) méthode que j'ai trouvé pour obtenir la même fonctionnalité est la suivante:

# get the tracking-branch name
tracking_branch=$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))
# creates global variables $1 and $2 based on left vs. right tracking
# inspired by @adam_spiers
set -- $(git rev-list --left-right --count $tracking_branch...HEAD)
behind=$1
ahead=$2

réponse originale à cette question: (inférieur, mais donné pour plus de clarté)

Peut-être la méthode la plus simple que j'ai pu trouver (inspiré par @insidepower)

# count the number of logs
behind=$(git log --oneline HEAD..origin | wc -l)
ahead=$( git log --oneline origin..HEAD | wc -l)

J'avais déjà été à l'aide de la méthode de @araqnid, mais maintenant je pense que je vais passer certains de mes scripts pour cette méthode, car il est beaucoup plus simple. Cela devrait fonctionner sur tout système unix.

6voto

Hamish Downer Points 4086

git status a --porcelain option qui est destiné pour l'analyse par des scripts. Il est basé sur l' --short sortie - ils sont presque identiques au moment de la rédaction (voir la "Porcelaine" Format de la section de l' git status page de manuel pour plus de détails.

Par défaut, aucune information de la direction générale est montré, mais si vous ajoutez l' --branch option, vous obtiendrez de sortie comme:

git status --short --branch
## master...origin/master [ahead 1]
?? untrackedfile.txt
...

Si vous êtes à jour (après une extraction), la direction de la ligne sera juste:

## master

Si vous êtes en avance:

## master...origin/master [ahead 1]

Si vous êtes en retard:

## master...origin/master [behind 58]

Et pour les deux:

## master...origin/master [ahead 1, behind 58]

Notez que git status --porcelain --branch n'est disponible que dans 1.7.10.3 ou plus tard (même si git status --short --branch a été disponible depuis la 1.7.2 ).

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