Comment puis-je voir quelles branches Git suivent quelle branche distante / en amont?


825

Je sais que je peux le faire git branch --all, et cela me montre à la fois les succursales locales et distantes, mais ce n'est pas très utile pour me montrer les relations entre elles.

Comment puis-je répertorier les branches d'une manière qui montre quelle branche locale suit quelle télécommande?

Réponses:


1146

Très bien une commande en porcelaine, pas bonne si vous voulez cela pour le script:

git branch -vv   # doubly verbose!

Notez qu'avec git 1.8.3, cette branche en amont est affichée en bleu (voir " Quel est ce suivi de branche (le cas échéant) dans git? ")


Si vous voulez une sortie propre, voir la réponse d'arcresu - il utilise une commande porcelaine qui, je ne pense pas, existait au moment où j'ai écrit cette réponse, donc c'est un peu plus concis et fonctionne avec des branches configurées pour rebaser, pas seulement fusionner.


3
La première méthode ci-dessus ne me fournit pas les informations souhaitées. Le second ... semble exagéré, d'autant plus que la réponse de Kubi fonctionne. Suis-je en train de manquer quelque chose?
garyp

3
@garyp Ce n'est pas vous qui avez posé la question. Le premier a fourni ce dont l'OP avait besoin, et le second a fourni exactement ce dont il avait besoin, au cas où il le voudrait sous une forme propre pour l'écriture de scripts, ou voulait simplement l'enregistrer en tant qu'alias. ("Overkill" est très bien s'il vous obtient ce que vous voulez et que vous n'avez pas à le répéter.) Du point de vue de cette question, la réponse de kubi fournit des informations étrangères, et s'il y a plus d'une télécommande, elle ne fonctionne pas ne montrez pas tout, mais si cela répond à vos besoins, utilisez-le par tous les moyens.
Cascabel

2
Je dois des excuses. Lorsque j'ai initialement exécuté la première méthode, je n'ai obtenu aucune information sur ce qui suit quoi, et j'aurais dû le dire explicitement. Mais maintenant, je vois les informations de suivi, je dois donc avoir eu quelque chose de mal avec ma configuration. Donc , je me manque quelque chose.
garyp

2
FWIW J'étais confus car -v et -vv affichent une sortie similaire. La branche suivie est affichée entre crochets après le hachage et avant le commit le plus récent (sur mon installation homebrew OSX par défaut).
jerclarke

3
Pour moi, tout cela consiste à imprimer le dernier hachage de validation et les commentaires pour chaque branche.
capybaralet

263

git remote show origin

Remplacez «origine» par le nom de votre télécommande.


11
Même si cette commande de porcelaine fonctionne un peu pour un humain (pas tellement pour un script, car elle devrait analyser la sortie de porcelaine), ce que je n'aime pas dans cette approche, c'est que la git remote showcommande se connecte réellement au référentiel distant ... et par conséquent, il échoue si vous êtes hors ligne ou incapable de vous connecter au référentiel pour une raison quelconque ...
pvandenberk

17
@pvandenberk Vous pouvez utiliser git remote show -n originpour obtenir des informations même hors ligne. Dans la documentation git remote : "Avec l'option -n, les têtes distantes ne sont pas interrogées en premier avec git ls-remote <nom>; les informations mises en cache sont utilisées à la place."
Cerran

5
Une chose étrange à propos de cette commande: elle répertorie les branches distantes comme "suivies", même s'il n'y a pas de branche locale configurée pour tirer / pousser. Je trouve toujours cela déroutant. Je ne sais pas vraiment ce que "suivi" est censé signifier dans cette sortie. Les git docs sur le sujet donnent l'impression qu'une branche distante n'est "suivie" que lorsqu'elle est liée / liée à une branche locale pour pousser / tirer ...
Hawkeye Parker

Le problème est que je dois l'appeler pour tous les noms distants jusqu'à ce que je voie ce que je recherche réellement.
jolvi

2
@jolvi Vous pouvez exécuter git remote show | xargs git remote show -npour afficher les informations de suivi combinées pour toutes les télécommandes.
Synoli

107

Si vous consultez la page de manuel de git-rev-parse, vous verrez que la syntaxe suivante est décrite:

<branchname>@{upstream}, par exemple master@{upstream},@{u}

Le suffixe @{upstream}d'un nom de branche (forme abrégée <branchname>@{u}) fait référence à la branche sur laquelle la branche spécifiée par nom de branche doit être créée. Un nom de branche manquant par défaut est le nom actuel.

Donc pour trouver l'amont de la branche master, vous feriez:

git rev-parse --abbrev-ref master@{upstream}
# => origin/master

Pour imprimer les informations de chaque branche, vous pouvez faire quelque chose comme:

while read branch; do
  upstream=$(git rev-parse --abbrev-ref $branch@{upstream} 2>/dev/null)
  if [[ $? == 0 ]]; then
    echo $branch tracks $upstream
  else
    echo $branch has no upstream configured
  fi
done < <(git for-each-ref --format='%(refname:short)' refs/heads/*)

# Output:
# master tracks origin/master
# ...

C'est plus propre que d'analyser les références et de configurer manuellement.


Je ne pouvais pas comprendre ce bit en rev-parse malgré le trouver, alors merci pour l'explication claire!
Alice Purcell

3
Pour ceux d'entre nous qui utilisent git-flow, avec des branches nommées "feature / blahblah", l'instruction de fermeture de la boucle while devrait se lire: done < <(git for-each-ref --format='%(refname:short)' refs/heads/**)Notez les deux astérisques à la fin du modèle glob.
markeissler

2
git rev-parse --abbrev-ref HEAD@{upstream}semble bien fonctionner pour la branche actuelle. Cela fait également un joli alias git.
Digikata

La whilesyntaxe de boucle me semble un peu bizarre. Vous pouvez simplement utiliser git for-each-ref ... | while read branch; do ...ce qui n'a pas besoin d'un FIFO et s'exécute dans le même ordre que les commandes écrites.
Daniel Böhmer

Au moins depuis git 2.5.1, vous avez un one-liner avecgit for-each-ref --format='%(refname:short) tracks %(upstream:short)' refs/heads/*
Mat M

81

Une alternative à la réponse de kubi est de jeter un œil au .git/configfichier qui montre la configuration du référentiel local:

cat .git/config


6
Aussi git config --get-regex branch
Tamir Daniely

6
Ou, plus précisément, 'git config --get-regexp branch. * Merge'
yoyo

41
git for-each-ref --format='%(refname:short) <- %(upstream:short)' refs/heads

affichera une ligne pour chaque branche locale. Une branche de suivi ressemblera à:

master <- origin/master

Un non-suivi ressemblera à:

test <- 

Agréable, pour ajouter un peu d'ordre et de sortie de lit TAB: git for-each-ref --sort upstream --format = '% (refname: short)% 09 <-% (upstream: short)'
refs

Magnifiquement concis et la sortie est en fait beaucoup plus lisible que celle acceptée git branch -vv. 🙏
joki

Le seul problème est que je ne m'en souviens pas, j'ai donc utilisé git config --global alias.track 'for-each-ref --format='\''%(refname:short) <- %(upstream:short)'\'' refs/heads'
joki

38

Pour la branche actuelle , voici deux bons choix:

% git rev-parse --abbrev-ref --symbolic-full-name @{u}
origin/mainline

ou

% git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)
origin/mainline

Cette réponse se trouve également ici , à une question légèrement différente qui a été (à tort) marquée comme doublon.


5
Sur cette base, toutes les branches peuvent être répertoriées dans un script mode convivial: git for-each-ref --shell --format='%(refname:short) %(upstream:short)' refs/heads.
Daniel James

15

Pour la branche actuelle, vous pouvez également dire git checkout(sans aucune branche). Il s'agit d'un no-op avec des effets secondaires pour afficher les informations de suivi, si elles existent, pour la branche actuelle.

$ git checkout 
Your branch is up-to-date with 'origin/master'.

Assez juste, mais vous pouvez taper accidentellement git checkout ., ce qui n'est pas un no-op.
Tomasz Gandor

6

J'utilise cet alias

git config --global alias.track '!f() { ([ $# -eq 2 ] && ( echo "Setting tracking for branch " $1 " -> " $2;git branch --set-upstream $1 $2; ) || ( git for-each-ref --format="local: %(refname:short) <--sync--> remote: %(upstream:short)" refs/heads && echo --Remotes && git remote -v)); }; f'

puis

git track

5
Je pense qu'il vaut la peine de noter qu'avec deux paramètres, votre commande configure une branche de piste.
albfan

3

D'après la réponse d'Olivier Refalo

if [ $# -eq 2 ] 
then
    echo "Setting tracking for branch " $1 " -> " $2
    git branch --set-upstream $1 $2
else
    echo "-- Local --" 
    git for-each-ref --shell --format="[ %(upstream:short) != '' ] && echo -e '\t%(refname:short) <--> %(upstream:short)'" refs/heads | sh
    echo "-- Remote --" 
    REMOTES=$(git remote -v) 
    if [ "$REMOTES" != '' ]
    then
        echo $REMOTES
    fi  
fi

Il affiche uniquement local avec piste configurée.

Écrivez-le sur un script appelé git-track sur votre chemin et vous obtiendrez une commande git track

Une version plus élaborée sur https://github.com/albfan/git-showupstream


1

git config --get-regexp "branch\.$current_branch\.remote"

vous donnera le nom de la télécommande qui est suivie

git config --get-regexp "branch\.$current_branch\.merge"

vous donnera le nom de la branche distante qui est suivie.

Vous devrez remplacer $ current_branch par le nom de votre branche actuelle. Vous pouvez obtenir cela dynamiquement avecgit rev-parse --abbrev-ref HEAD

Le mini-script suivant combine ces choses. Collez-le dans un fichier nommégit-tracking , rendez-le exécutable et assurez-vous qu'il se trouve sur votre chemin.

alors tu peux dire

$ git  tracking
<current_branch_name>-><remote_repo_name>/<remote_branch_name>

notez que le nom de la branche distante peut être différent du nom de votre branche locale (bien qu'il ne le soit généralement pas). Par exemple:

$git tracking 
xxx_xls_xslx_thing -> origin/totally_bogus

comme vous pouvez le voir dans le code, la clé est d'extraire les données de la configuration git. J'utilise simplement sed pour effacer les données superflues.

#!/bin/sh

current_branch=$(git rev-parse --abbrev-ref HEAD)
remote=$(git config --get-regexp "branch\.$current_branch\.remote" | sed -e "s/^.* //")
remote_branch=$(git config --get-regexp "branch\.$current_branch\.merge" | \
  sed -e "s/^.* //" -e "s/refs\/.*\///")

echo "$current_branch -> $remote/$remote_branch"

1

En voici une nette et simple. Peut vérifier git remote -v, qui vous montre toute l'origine et en amont de la branche actuelle.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.