web-dev-qa-db-fra.com

Supprimer toutes les branches git locales

Je suis un processus de développement dans lequel je crée une nouvelle branche locale pour chaque nouvelle fonctionnalité ou carte d’histoire. Une fois terminé, je fusionne la branche en maître, puis en Push. 

Ce qui a tendance à se produire avec le temps en raison d’une combinaison de paresse et d’oubli, c’est que je me retrouve avec une longue liste de succursales locales, dont certaines (comme les pics) peuvent ne pas avoir été fusionnées.

Je sais comment répertorier toutes mes branches locales et comment supprimer une seule branche, mais je me demandais s'il existait une commande git qui me permet de supprimer toutes mes branches locales?

Vous trouverez ci-dessous le résultat de la commande git branch --merged.

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) génèrent 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.

J'utilise:
git 1.7.4.1
Ubuntu 10.04
GNU bash, version 4.1.5 (1) - release
GNU grep 2.5.4 

208
Louth

Juste une note, je passerais à git 1.7.10. Vous obtiendrez peut-être ici des réponses qui ne fonctionneront pas avec votre version. Mon hypothèse est qu'il faudrait préfixer le nom de la branche avec refs/heads/.

ATTENTION, ne procédez comme suit que si vous avez copié votre dossier de travail et votre répertoire .git.

Parfois, je ne fais que supprimer les branches que je ne veux pas directement de .git/refs/heads. Toutes ces branches sont des fichiers texte contenant les 40 caractères sha-1 du commit sur lequel ils pointent. Vous aurez des informations superflues dans votre .git/config si vous avez configuré un suivi spécifique pour l'un d'entre eux. Vous pouvez également supprimer ces entrées manuellement.

36
Adam Dymitruk

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

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

ou encore simplifié pour:

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

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

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

Attention justifiée lors des 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).
263
GoZoner

J'ai trouvé un moyen plus agréable dans un commentaire sur ce problème sur github :

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

edit: a ajouté l'option sans couleur et en excluant les branches stables (ajoutez d'autres branches selon vos besoins)

121
mBardos

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

  1. git branch est ce qu'on appelle une commande de porcelaine. Les commandes de porcelaine ne sont pas conçues pour être analysées par la machine et la sortie peut changer entre les différentes versions de Git. 
  2. Certaines options de configuration de l'utilisateur modifient la sortie de git branch de manière à rendre l'analyse difficile (par exemple, la colorisation). Si un utilisateur a défini color.branch, vous obtiendrez des codes de contrôle dans la sortie. Cela conduira à error: branch 'foo' not found. si vous essayez de le canaliser vers une autre commande. Vous pouvez éviter cela avec l'indicateur --no-color à git branch, mais qui sait quelles autres configurations utilisateur pourraient briser des choses.
  3. git branch peut faire d'autres choses qui sont ennuyeuses à analyser, comme mettre un astérisque à côté de la branche actuellement extraite

Le mainteneur de git a ceci à dire à propos des scripts autour de la sortie de git branch

Pour savoir ce qu’est la branche actuelle, les utilisateurs occasionnels/négligents peuvent avoir scripté autour de la branche git, ce qui est faux. Nous décourageons activement contre l'utilisation de toute commande de porcelaine, y compris la branche git, dans scripts, car la sortie de la commande est sujette à changer en aider cas d'utilisation de la consommation humaine.

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

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

Git 2.7.X introduira l’option --merged afin que vous puissiez faire quelque chose comme ci-dessous pour trouver et supprimer toutes les branches fusionnées dans HEAD 

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

À partir de Git 2.6.X, vous devrez répertorier toutes les branches locales, puis les tester individuellement pour voir si elles ont été fusionnées (ce qui sera beaucoup 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
67
Andrew C

Pour supprimer toutes les branches sauf celle que vous avez empruntée:

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

Je recommanderais de remplacer git branch -D $b par un echo $b les premières fois afin de vous assurer qu'il supprime les branches souhaitées.

45
sblom

La manière la plus simple de supprimer toutes les branches, mais de garder les autres comme "develop" et "master" est la suivante:

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D

très utile !

32
geoom

J'ai trouvé plus facile d'utiliser simplement l'éditeur de texte et Shell.

  1. Tapez git checkout <TAB> dans le shell. Montrera toutes les branches locales.
  2. Copiez-les dans un éditeur de texte, supprimez ceux que vous devez conserver.
  3. Remplacez les sauts de ligne par des espaces. (Dans SublimeText c'est super facile.)
  4. Open Shell, tapez git branch -D <PASTE THE BRANCHES NAMES HERE>.

C'est tout.

23
culebrón

La commande ci-dessous supprimera toutes les branches locales à l'exception de la branche principale.

git branch | grep -v "master" | xargs git branch -D

La commande ci-dessus

  1. lister toutes les branches
  2. Dans la liste, ignorez la branche principale et prenez le reste des branches.
  3. supprimer la branche
21
Hunter

J'ai eu un genre de situation similaire et récemment trouvé la commande suivante utile.

git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep>/) printf "%s", $0 }'`

Si vous voulez conserver plusieurs branches, alors

git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep1>|<Branch_You_Want_to_Keep2>/) printf "%s", $0 }'`

espérons que cela aide quelqu'un.

11
4u.Ans

Si vous n'avez pas besoin de passer par Git lui-même, vous pouvez également supprimer les en-têtes sous .git/refs/heads manuellement ou par programme. Ce qui suit devrait fonctionner avec un minimum de peaufinage sous Bash:

shopt -s extglob
rm -rf .git/refs/heads/!(master)

Cela supprimera toutes les branches locales à l'exception de votre branche principale. Puisque vos branches en amont sont stockées sous .git/refs/remotes , elles resteront intactes.

Si vous n'utilisez pas Bash, ou voulez rediffuser un grand nombre de référentiels Git à la fois, vous pouvez faire quelque chose de similaire avec GNU trouver:

find . \
    -path remotes -path logs -Prune -o \
    -wholename \*.git/refs/heads/\* \! -name master -print0 |
xargs -0 rm -rf

La solution de recherche est probablement plus portable, mais les chemins d’élagage et les noms de fichiers sont délicats et potentiellement plus sujets aux erreurs.

7
Todd A. Jacobs

Pour supprimer toutes les branches locales de Linux sauf celui sur lequel vous vous trouvez

// hard delete

git branch -D $(git branch)
5
ashish yadav

Aucune des réponses ne satisfaisait pleinement mes besoins, alors allons-y:

git branch --merged | grep -E "(feature|bugfix|hotfix)/" | xargs git branch -D && git remote Prune Origin

Cela supprimera toutes les branches locales qui sont fusionnées et qui commencent par feature/, bugfix/ ou hotfix/. Ensuite, la Origin distante amont est supprimée (vous devrez peut-être entrer un mot de passe).

Fonctionne sur Git 1.9.5.

4
user4401817

Basé sur une combinaison de plusieurs réponses ici - si vous voulez conservez toutes les branches qui existent à distance mais supprimez le reste , la solution suivante fera l'affaire:

git for-each-ref --format '%(refname:short)' refs/heads | grep -Ev `git ls-remote --quiet --heads Origin | awk '{print substr($2, 12)}'| paste -sd "|" -` | xargs git branch -D
3
Srishan Bhattarai

A partir de la ligne de commande Windows, supprimez tout sauf la branche extraite actuelle en utilisant:

for /f "tokens=*" %f in ('git branch ^| find /v "*"') do git branch -D %f
1
kiewic

Les réponses ci-dessus fonctionnent bien. Voici une autre approche lorsque nous avons beaucoup de succursales dans le dépôt local et que nous devons supprimer beaucoup de succursales, sauf quelques-unes qui se trouvent dans la machine locale. 

Le premier git branch listera toutes les branches locales.

Pour transposer la colonne de noms de branches en une seule ligne de fichier en exécutant une commande unix
git branch > sample.txt 
Ceci sera sauvegardé dans sample.txt fichier . Et lancera
awk 'BEGIN { ORS = " " } { print }' sample.txt 
commande dans Shell. Cela transformera la colonne en ligne et copiera la liste des noms de branches sur une seule ligne.

Et puis courir 
git branch -D branch_name(s)
Ceci supprimera toutes les branches listées présentes dans

0
Deepak G

La manière la plus pragmatique: assurez-vous de ne pas avoir de travail non engagé sur master, commit/Push si nécessaire, clonez une nouvelle copie du référentiel et supprimez l'ancien.

0
Patrick Sanan

J'ai écrit un script Shell afin de supprimer toutes les branches locales sauf develop

branches=$(git branch | tr -d " *")
output=""
for branch in $branches 
do
  if [[ $branch != "develop" ]]; then
    output="$output $branch"
  fi
done
git branch -d $output
0
nhp

Le script suivant supprime les branches. Utilisez-le et modifiez-le à vos risques et périls, etc. etc.

Sur la base des autres réponses à cette question, j'ai fini par écrire un script rapide pour moi-même. Je l'ai appelé "gitbd" (git branch -D) mais si vous l'utilisez, vous pouvez le renommer comme vous le souhaitez.

gitbd() {
if [ $# -le 1 ]
  then
    local branches_to_delete=`git for-each-ref --format '%(refname:short)' refs/heads/ | grep "$1"`
    printf "Matching branches:\n\n$branches_to_delete\n\nDelete? [Y/n] "
    read -n 1 -r # Immediately continue after getting 1 keypress
    echo # Move to a new line
    if [[ ! $REPLY == 'N' && ! $REPLY == 'n' ]]
      then
        echo $branches_to_delete | xargs git branch -D
    fi
else
  echo "This command takes one arg (match pattern) or no args (match all)"
fi
}

Elle proposera de supprimer toutes les branches qui correspondent à un argument de modèle, si elles sont passées, ou toutes les branches locales si elles sont appelées sans argument. Cela vous donnera également une étape de confirmation, puisque, vous savez, nous supprimons des éléments, c’est bien Nice.

C'est un peu bête - s'il n'y a pas de branches qui correspondent au modèle, il ne s'en rend pas compte.

Un exemple de sortie:

$ gitbd test
Matching branches:

dummy+test1
dummy+test2
dummy+test3

Delete? [Y/n] 
0
dherman

Pour Powershell, cela fonctionnera:

git branch --format '%(refname:lstrip=2)' --merged `
    | Where-Object { $_ -ne 'master' } `
    | ForEach-Object { git branch -d $_ }
0
Lucas

Assurez-vous de le faire en premier

git fetch

Une fois que vous avez toutes les informations sur les branches distantes, utilisez la commande suivante pour supprimer toutes les branches sauf master

 git branch -a | grep -v "master" | grep remotes | sed 's/remotes\/Origin\///g' | xargs git Push Origin --delete
0
Meng

Bien que ce ne soit pas une solution en ligne de commande, je suis surpris que l'interface graphique Git n'ait pas encore été suggérée.

J'utilise la ligne de commande 99% du temps, mais dans ce cas, il est trop lent (d'où la question initiale) ou vous ne savez pas ce que vous êtes sur le point de supprimer lorsque vous aurez recours à une manipulation de Shell longue et astucieuse.

L'interface utilisateur résout ce problème, car vous pouvez rapidement cocher les branches que vous souhaitez supprimer et être rappelé à celles que vous souhaitez conserver, sans avoir à taper une commande pour chaque branche.

Dans l'interface utilisateur, accédez à Branche -> Supprimer et à Ctrl + Clic les branches que vous souhaitez supprimer pour les mettre en surbrillance. Si vous voulez vous assurer qu'ils sont fusionnés dans une branche (telle que dev), sous Supprimer uniquement si fusionné dans, définissez Local Branch sur dev. Sinon, réglez-le sur Toujours pour ignorer cette vérification. 

 GitUI: delete local branches

0
Dane Bouchie