534 votes

Supprimer toutes les branches git locales

Je suis un processus de développement où je crée une nouvelle branche locale pour chaque nouvelle fonctionnalité ou story card. Une fois terminé, je fusionne la branche avec master et je pousse.

Ce qui tend à se produire avec le temps, à cause d'une combinaison de paresse et d'oubli, c'est que je me retrouve avec une grande liste de branches locales, dont certaines (comme les spikes) peuvent ne pas avoir été fusionnées.

Je sais comment lister toutes mes branches locales et je sais comment supprimer une seule branche mais je me demandais s'il existait une commande git qui me permette de supprimer toutes mes branches locales ?

Vous trouverez ci-dessous le résultat de l'opération git branch --merged commandement.

user@machine:~/projects/application[master]$ git branch --merged
  STORY-123-Short-Description
  STORY-456-Another-Description
  STORY-789-Blah-Blah
* master

Toutes les tentatives de suppression des branches listées avec grep -v \* (selon les réponses ci-dessous) entraînent des erreurs :

error: branch 'STORY-123-Short-Description' not found.
error: branch 'STORY-456-Another-Description' not found.
error: branch 'STORY-789-Blah-Blah' not found.

Je l'utilise :
git 1.7.4.1
ubuntu 10.04
GNU bash, version 4.1.5(1)-release
GNU grep 2.5.4

0 votes

Ce n'est pas une réponse, mais une chose à signaler, que je fais souvent, c'est que lorsque j'atteins le sommet de la paresse et que le clone local est très sale, j'ai simplement rm -rf /my_cool_repo et reclasser le repo. Si je n'ai pas de branche active, c'est le moyen le plus simple de "nettoyer toutes les branches locales". Ce n'est clairement pas la solution si vous travaillez activement sur une branche.

0 votes

@theJones Je ne recommanderais pas le re-clonage car vous perdriez toutes les modifications dans les fichiers non versionnés et ignorés, par exemple les projets IDE. La réponse la plus populaire ci-dessous a parfaitement fonctionné pour moi pendant des années.

647voto

GoZoner Points 15679

La sous-commande 'git branch -d' peut supprimer plus d'une branche. Donc, en simplifiant la réponse de @sblom mais en ajoutant un xargs critique :

git branch -D `git branch --merged | grep -v \* | xargs`

ou, encore simplifié à :

git branch --merged | grep -v \* | xargs git branch -D 

Il est important de noter, comme l'a fait remarquer @AndrewC, que l'utilisation de git branch pour les scripts est déconseillé. Pour l'éviter, utilisez quelque chose comme :

git for-each-ref --format '%(refname:short)' refs/heads | grep -v "master\|main" | xargs git branch -D

Attention aux suppressions !

$ mkdir br
$ cd br; git init
Initialized empty Git repository in /Users/ebg/test/br/.git/
$ touch README; git add README; git commit -m 'First commit'
[master (root-commit) 1d738b5] First commit
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README
$ git branch Story-123-a
$ git branch Story-123-b
$ git branch Story-123-c
$ git branch --merged
  Story-123-a
  Story-123-b
  Story-123-c
* master
$ git branch --merged | grep -v \* | xargs
Story-123-a Story-123-b Story-123-c
$ git branch --merged | grep -v \* | xargs git branch -D
Deleted branch Story-123-a (was 1d738b5).
Deleted branch Story-123-b (was 1d738b5).
Deleted branch Story-123-c (was 1d738b5).

0 votes

Cette commande rapporte toujours les mêmes erreurs que celles mentionnées dans les commentaires de la réponse ci-dessous. error:branch 'STORY-123-Short-Description' not found. pour chacune des branches énumérées.

1 votes

Cela fonctionne pour moi ; voir ci-dessus avec les détails ajoutés.

0 votes

Toutes les étapes que vous avez montrées fonctionnent pour moi, jusqu'à ce que git branch --merged | grep -v \* | xargs git branch -D et j'obtiens alors les erreurs que j'ai montrées dans la réponse.

189voto

mBardos Points 404

J'ai trouvé un moyen plus agréable dans un commentaire sur cette question sur github :

git branch --merged master --no-color | grep -v "master\|stable\|main" | xargs git branch -d

Modifier : Ajout de l'option no-color et exclusion de la branche stable (ajouter d'autres branches si nécessaire dans votre cas)

2 votes

Enfin, la solution que je cherchais

2 votes

J'ai essayé mais j'obtiens toujours error: branch 'my-branch-name' not found. pour chaque branche. J'utilise git version 1.8.3.4 (Apple Git-47). Une idée de la raison ?

0 votes

Essayez 'git branch --merged master | grep -v master | xargs echo' pour déboguer ce qu'il essaie exactement de supprimer ? je n'ai pas de meilleure idée...

156voto

Andrew C Points 3088

Analyse de la sortie de git branch n'est pas recommandé, et ne constitue pas une bonne réponse pour les futurs lecteurs de Stack Overflow.

  1. git branch est ce que l'on appelle une commande en porcelaine. Les commandes porcelaine ne sont pas conçues pour être analysées par la machine et la sortie peut changer entre différentes versions de Git.
  2. Il existe des options de configuration utilisateur qui modifient la sortie de git branch d'une manière qui rend l'analyse syntaxique difficile (par exemple, la colorisation). Si un utilisateur a défini color.branch alors vous obtiendrez des codes de contrôle dans la sortie, ce qui conduira à error: branch 'foo' not found. si vous essayez de l'intégrer dans une autre commande. Vous pouvez contourner cela avec l'option --no-color pour git branch mais qui sait si d'autres configurations d'utilisateurs peuvent perturber les choses.
  3. git branch peut faire d'autres choses qui sont ennuyeuses à analyser, comme mettre un astérisque à côté de la branche en cours de vérification

El Le responsable de git a déclaré ceci sur le scriptage autour git branch sortie

Pour savoir quelle est la branche actuelle, les utilisateurs occasionnels ou imprudents peuvent avoir recours à scripté autour de git branch, ce qui est faux. Nous décourageons activement l'utilisation de n'importe quelle commande Porcelain, y compris git branch, dans des scripts, parce que la sortie de la commande est sujette à changement pour aider le cas d'utilisation de la consommation humaine.

Les réponses qui suggèrent de modifier manuellement les fichiers dans le .git (comme .git/refs/heads) sont également problématiques (les refs peuvent se trouver dans .git/packed-refs à la place, ou Git peut changer leur disposition interne à l'avenir).

Git fournit le for-each-ref pour récupérer une liste de branches.

Git 2.7.X introduira la fonction --merged pour que vous puissiez faire quelque chose comme ce qui suit pour trouver et supprimer toutes les branches fusionnées en HEAD

for mergedBranch in $(git for-each-ref --format '%(refname:short)' --merged HEAD refs/heads/)
do
    git branch -d ${mergedBranch}
done

Git 2.6.X et plus ancien, vous devrez lister toutes les branches locales et ensuite les tester individuellement pour voir si elles ont été fusionnées (ce qui sera significativement plus lent et légèrement plus compliqué).

for branch in $(git for-each-ref --format '%(refname:short)' refs/heads/)
do
    git merge-base --is-ancestor ${branch} HEAD && git branch -d ${branch}
done

0 votes

git branch --no-color 2>/dev/null ?

7 votes

C'est une amélioration, c'est sûr. Vous aurez toujours le problème de devoir filtrer les *, et il fait des choses amusantes si quelqu'un le fait fonctionner à partir d'une tête détachée. Le problème principal est cependant git branch est une commande de porcelaine, et il n'y a aucune garantie que la sortie ne changera pas dans une future version de git.

0 votes

Merci @AndrewC - ceci répond à la fois à la question concernant les mystérieuses erreurs "branch not found" et fournit une solution fonctionnelle utilisant une commande plus appropriée !

67voto

sblom Points 15074

Pour supprimer toutes les branches à l'exception de celle que vous avez actuellement vérifiée :

for b in `git branch --merged | grep -v \*`; do git branch -D $b; done

Je recommanderais de changer git branch -D $b à un echo $b les premières fois pour s'assurer qu'il supprime les branches que vous voulez.

1 votes

Avec cette commande j'obtenir error:branch 'a_branch_name' not found. Je vois ce que vous essayez de faire et j'ai joué avec la commande mais pour une raison quelconque, git ne semble pas aimer les noms de branches fournis...

0 votes

Hmmm. pour aider à résoudre le problème, il serait utile de voir un exemple de sortie de l'ordinateur. git branch --merged

0 votes

Mes noms de branches sont au format STORY-123-Short-Description

43voto

Adam Dymitruk Points 34999

Juste une remarque, je mettrais à jour vers git 1.7.10. Vous pouvez obtenir des réponses ici qui ne fonctionnent pas avec votre version. Je pense que vous devriez préfixer le nom de la branche par refs/heads/ .

ATTENTION, ne procédez à ce qui suit que si vous avez fait une copie de votre dossier de travail et de votre répertoire .git.

Parfois, je supprime les branches que je ne veux pas directement à partir de la page d'accueil. .git/refs/heads . Toutes ces branches sont des fichiers texte qui contiennent le sha-1 de 40 caractères du commit vers lequel elles pointent. Vous aurez des informations étrangères dans votre .git/config si vous avez mis en place un suivi spécifique pour l'un d'entre eux. Vous pouvez également supprimer ces entrées manuellement.

0 votes

Enfin une option simple et pragmatique. Je l'aime bien :D

2 votes

Cela ne fonctionnera pas si vous avez des références emballées, ou même si vous avez parfois cloné à partir d'un serveur distant (qui vous fournira des fichiers emballés). Si vos refs sont empaquetées, alors les refs ne seront pas stockées dans .git/refs/heads, elles seront stockées dans un fichier appelé "packed-refs". Voir git-scm.com/docs/git-pack-refs .

1 votes

Il semble que ce soit une mauvaise idée de supprimer la branche que vous avez extraite pour le moment.

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