126 votes

Lister toutes les branches locales sans télécommande

Problème : Je veux un moyen de supprimer toutes les branches locales que j'ai et qui n'ont pas de télécommande. Il est assez facile de mettre les noms des branches dans un fichier git branch -D {branch_name} mais comment obtenir cette liste en premier lieu ?

Par exemple :

Je crée une nouvelle branche sans télécommande :

$ git co -b no_upstream

Je liste toutes mes branches, et il n'y en a qu'une avec une télécommande

$ git branch -a
master
* no_upstream
remotes/origin/HEAD -> origin/master
remotes/origin/master

Quelle commande puis-je lancer pour obtenir no_upstream comme réponse ?

Je peux courir git rev-parse --abbrev-ref --symbolic-full-name @{u} et cela montrera qu'il n'a pas de télécommande :

$ git rev-parse --abbrev-ref --symbolic-full-name @{u}
error: No upstream configured for branch 'no_upstream'
error: No upstream configured for branch 'no_upstream'
fatal: ambiguous argument '@{u}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

Mais comme il s'agit d'une erreur, je ne peux pas l'utiliser ou la transmettre à d'autres commandes. J'ai l'intention de l'utiliser soit comme un script shell aliasé à git-delete-unbranched ou peut-être faire un Gem super simple comme git-branch-delete-orphans

146voto

Jeremy Baker Points 891

Je recommande d'utiliser git branch --format pour spécifier la sortie exacte que vous souhaitez obtenir de la git branch commande. En faisant cela, vous pouvez extraire seulement le nom de référence et l'amont, comme ceci :

git branch --format "%(refname:short) %(upstream)"

Il produit les branches ainsi que les branches distantes si elles existent, dans le format suivant :

25-timeout-error-with-many-targets
31-target-suggestions refs/remotes/origin/31-target-suggestions
54-feedback-link refs/remotes/origin/54-feedback-link
65-digest-double-publish

Une fois que vous avez obtenu cette sortie joliment formatée, il suffit de la faire passer par le canal awk pour obtenir votre liste :

git branch --format "%(refname:short) %(upstream)" | awk '{if (!$2) print $1;}'

Le résultat est le suivant :

25-timeout-error-with-many-targets
65-digest-double-publish

El awk imprime la première colonne s'il n'y a pas de deuxième colonne.

Bonus : créer un alias

Pour faciliter l'exécution, créez un alias dans votre fichier global. .gitconfig (ou ailleurs) :

[alias]
  local-branches = "!git branch --format '%(refname:short) %(upstream:short)' | awk '{if (!$2) print $1;}'"

Bonus : Filtrage à distance

Si, pour une raison ou une autre, vous avez plusieurs télécommandes de suivi pour différentes branches, il est assez facile de spécifier à quelle télécommande vous voulez faire la vérification. Il suffit d'ajouter le nom du distant au motif awk. Dans mon cas, c'est origin pour que je puisse faire ça :

git branch --format "%(refname:short) %(upstream)" | awk '$2 !~/\/origin\// { print $1 }'

Important : la barre oblique inverse doit être échappée dans l'alias, sinon vous aurez un fichier gitconfig invalide.


Réponse précédente

La réponse précédente était fonctionnellement similaire, mais utilisait les éléments suivants comme point de départ. Au fil du temps, des commentateurs ont fait remarquer qu'une regex n'était pas fiable en raison de la variance possible dans un message de livraison, aussi je ne recommande plus cette méthode. Mais, la voici pour référence :

J'ai récemment découvert git branch -vv qui est la version "très verbeuse" de la fonction git branch commandement.

Il produit les branches ainsi que les branches distantes si elles existent, dans le format suivant :

  25-timeout-error-with-many-targets    206a5fa WIP: batch insert
  31-target-suggestions                 f5bdce6 [origin/31-target-suggestions] Create target suggestion for team and list on save
* 54-feedback-link                      b98e97c [origin/54-feedback-link] WIP: Feedback link in mail
  65-digest-double-publish              2de4150 WIP: publishing-state

Une fois que vous avez obtenu cette sortie joliment formatée, il suffit de la faire passer par le canal cut y awk pour obtenir votre liste :

git branch -vv | cut -c 3- | awk '$3 !~/\[/ { print $1 }'

39voto

VonC Points 414372

git branch (sans aucune option) ne liste que les branches locales, mais vous ne savez pas si elles suivent une branche distante ou non.

Habituellement, ces branches locales devraient être supprimées une fois fusionnées dans master (comme vu dans ce numéro de git-sweep ):

git branch --no-contains master --merged master | xargs git branch -d

Ce n'est pas aussi complet que vous le souhaitez, mais c'est un début.

Avec --merged seules les branches fusionnées dans le commit nommé (i.e. les branches dont les derniers commits sont accessibles depuis le commit nommé) seront listées.

26voto

Karl Wilbur Points 3089

J'ai un problème similaire. Je veux supprimer toutes les branches locales qui suivaient des branches distantes qui sont maintenant supprimées. Je constate que git remote prune origin était insuffisante pour enlever les branches que je veux voir disparaître. Une fois que le distant est supprimé, je veux que le local disparaisse aussi. Voici ce qui a fonctionné pour moi :

De mon ~/.gitconfig :

[alias]
  prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -d

Voici un git config --global ... pour l'ajouter facilement comme git prune-branches :

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d'

NOTE : J'ai changé le -d a -D dans ma configuration actuelle, car je ne veux pas entendre Git se plaindre de branches nonmergées. Vous mai veulent également cette fonctionnalité. Dans ce cas, il suffit d'utiliser -D au lieu de -d à la fin de cette commande.

De plus, pour info, votre fichier de configuration globale sera presque toujours ~/.gitconfig .

(Correction OS X)

Telle qu'elle est écrite, cette méthode ne fonctionne pas sous OS X en raison de l'utilisation de l'option xargs -r (merci, Korny ).

El -r est d'empêcher xargs de la course git branch -d sans nom de branche, ce qui entraînera un message d'erreur " fatal: branch name required ". Si le message d'erreur ne vous dérange pas, vous pouvez simplement supprimer l'option -r argument pour xargs et vous êtes prêt.

Cependant, si vous ne voulez pas voir un message d'erreur (et vraiment, qui pourrait vous en blâmer), vous aurez besoin de quelque chose d'autre qui vérifie si le tuyau est vide. Si vous pouvez utiliser ifne de moreutils . Vous devez insérer ifne avant xargs qui arrêtera xargs de fonctionner avec des données vides. NOTE : ifne considère tout ce qui est ne doit pas être vide, ce qui inclut les lignes vides, donc vous pouvez toujours voir ce message d'erreur. Je n'ai pas testé cela sous OS X.

C'est ici git config ligne avec ifne :

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | ifne xargs git branch -d'

20voto

jthill Points 10384

Modification tardive :

Le mieux est

git for-each-ref  --format='%(refname:short) %(upstream)'  refs/heads \
| awk '$2 !~/^refs\/remotes/'

Sur GNU/tout

for b in `git branch|sed s,..,,`; do
    git config --get branch.$b.remote|sed Q1 && echo git branch -D $b
done

Si plus d'une poignée de branches étaient probables, il y aurait de meilleures façons, en utilisant comm -23 sur la sortie de git branch|sed|sort y git config -l|sed|sort .

18voto

ebr Points 568

Cela fonctionne pour moi :

git branch -vv | grep -v origin

(si le nom de votre télécommande est différent de celui d'origine, remplacez-le).

Vous obtiendrez ainsi la liste de toutes les succursales qui n'effectuent pas de suivi à distance, ce qui ressemble à ce que vous recherchez.

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