Pouvez-vous supprimer plusieurs branches en une seule commande avec Git?

355

Je voudrais nettoyer mon dépôt local, qui a une tonne de vieilles branches: par exemple 3.2, 3.2.1, 3.2.2, etc.

J'espérais un moyen sournois d'en supprimer beaucoup à la fois. Comme ils suivent principalement une convention de libération de points, j'ai pensé qu'il y avait peut-être un raccourci pour dire:

git branch -D 3.2.*

et tuez toutes les branches 3.2.x.

J'ai essayé cette commande et cela, bien sûr, n'a pas fonctionné.

Doug
la source
11
git branch -D $(git branch | grep 3.2*)- cela a fonctionné pour moi. Il supprime les branches dont le nom commence par "3.2". grep- correspondance de motifs dans la sortie (de git branchdans ce cas). $()- signifie exécuter et placer le résultat. |- enchaînement.
Eduard
4
Il convient de noter que pour ceux qui ne savent pas, c'est -Dune suppression forcée , devrait utiliser -ddans la plupart des cas pour être plus sûr en premier.
redfox05

Réponses:

363

Pas avec cette syntaxe. Mais vous pouvez le faire comme ceci:

git branch -D 3.2 3.2.1 3.2.2

Fondamentalement, git branch supprimera plusieurs branches pour vous avec une seule invocation. Malheureusement, il ne complète pas le nom de la branche. Bien que, en bash, vous pouvez faire:

git branch -D `git branch | grep -E '^3\.2\..*'`
Slebetman
la source
3
L'achèvement des git branch -D/-dtravaux fonctionne bien pour moi. Pourrait vouloir mettre à jour le vôtre (peut-être à partir du répertoire contrib git.git le plus récent).
Cascabel
19
Au lieu de git branch | ...vous pourriez utiliser $(git for-each-ref --format='%(refname:short)' refs/heads/3.*). C'est plus long, je sais, mais il est garanti d'être une sortie appropriée, tout en git branchayant une jolie sortie avec des choses comme *et ->(pour les symréfs) qui peuvent vous gâcher dans les scripts / one-liners.
Cascabel
3
Peut-être que je suis le seul à avoir ce problème, mais j'ai un grepalias pour toujours inclure le drapeau --color=always- git branch -Djetait error: branch 'my_branch' not found.jusqu'à ce que je coure sans le drapeau de couleur.
eebbesen
@eebbesen L'avez-vous désactivé globalement? Je rencontre le même problème lors de l'exécutiongit branch --merged ${1-$(current_branch)} | grep -v ${1-$(current_branch)} | xargs git branch -d
qmmr
2
Avec l'extension d'accolade, vous pouvez écrire git branch -D 3.2{,.1,.2}pour supprimer les trois branches gnu.org/software/bash/manual/html_node/Brace-Expansion.html
robstarbuck
147

Eh bien, dans le pire des cas, vous pouvez utiliser:

git branch | grep '3\.2' | xargs git branch -d
Carl Norum
la source
22
C'est à peu près la méthode parfaite pour quiconque utilise une notation de préfixe normalisée pour les noms de branche (par exemple "fix / ..." ou "feature / ...").
Haz
4
Simple et efficace! Je recommanderais cependant d'exécuter d'abord sans la | xargs git branch -dpartie pour vérifier ce qui va réellement être supprimé.
mathielo
Il est recommandé de ne pas grepsortir de git branch, car il est destiné à la lecture, pas à l'analyse. Pourrait changer à tout moment. utilisez le for-each-refavec les --formatparamètres, comme suggéré dans d'autres réponses, puis combinez-le avec les suggestions de cette réponse.
redfox05
138
git branch  | cut -c3- | egrep "^3.2" | xargs git branch -D
  ^                ^                ^         ^ 
  |                |                |         |--- create arguments
  |                |                |              from standard input
  |                |                |
  |                |                |---your regexp 
  |                |
  |                |--- skip asterisk 
  |--- list all 
       local
       branches

ÉDITER:

Une version plus sûre (suggérée par Jakub Narębski et Jefromi), car la sortie de la branche git n'est pas destinée à être utilisée dans les scripts:

git for-each-ref --format="%(refname:short)" refs/heads/3.2\* | xargs git branch -D

... ou sans xargs:

git branch -D `git for-each-ref --format="%(refname:short)" refs/heads/3.2\*`
gawi
la source
14
N'utilisez pas de git branchsortie pour les scripts. Utilisez git for-each-ref.
Jakub Narębski
1
Pour supprimer les balises avec le symbole @:git for-each-ref --format="%(refname:short)" refs/tags/\*@\* | xargs git tag -d
thaddeusmt
A une faute de frappe. Doit être "/3.2/*" et non "/3.2*". Il semble également que vous ayez copié d'autres réponses dans les vôtres.
Max MacLeod
Pas de faute de frappe ici. Depuis la page de manuel:If one or more patterns are given, only refs are shown that match against at least one pattern, either using fnmatch(3) or literally, in the latter case matching completely or from the beginning up to a slash
gawi
1
Il convient de noter que pour ceux qui ne savent pas, c'est -Dune suppression forcée , devrait utiliser -ddans la plupart des cas pour être plus sûr en premier.
redfox05
115

Vous pouvez utiliser git branch --list pour répertorier les branches éligibles et utiliser git branch -D / -d pour supprimer les branches éligibles.

Un exemple de doublure:

git branch -d `git branch --list '3.2.*'`
50shadesofbae
la source
Quand j'essaye ceci, j'obtiens un tas de messages d'erreur comme error: branch 'package.json' not found.. Il semble que le * soit développé trop tôt, et il essaie de supprimer une branche correspondant au nom de chaque fichier et répertoire.
Antimony
Ça marche bien! J'ai du gitconfig
mal à
6
Cette réponse doit être plus élevée dans la liste, super propre, fonctionne, pas de grep
jemiloii
1
Heureux que celui-ci soit facile à tester en premier en émettantgit branch --list '3.2.*'
Will
3
Aux fenêtresgit branch -d (git branch --list '3.2.*').trim()
Mattias Josefsson
38

Récemment, je cherchais une solution au même problème, j'ai finalement trouvé une réponse et cela fonctionne très bien:

  1. Ouvrez le terminal ou équivalent.
  2. Tapez dans git branch | grep "pattern" pour un aperçu des branches qui seront supprimées.
  3. Tapez dans git branch | grep "motif" | xargs git branch -D

Cette solution est géniale et si vous voulez une explication complète de chaque commande et comment elle fonctionne, elle est donnée ici .

KJ Gor
la source
28

Utilisation

git for-each-ref --format='%(refname:short)' 'refs/heads/3.2.*' |
   xargs git branch -D
Jakub Narębski
la source
7
petite astuce est que si vous supprimez la dernière partie de la commande "| xargs git branch -D" alors il ne restitue que les branches correspondantes. Vous pouvez donc prévisualiser les branches qui seront supprimées
Max MacLeod
1
J'ai également ajouté un alias pour simplifier cela: alias grefs='git for-each-ref --format="%(refname:short)"'je peux donc le fairegrefs | grep 'regexpattern' | xargs git branch -D
angularsen
J'ai adoré. Agréable et simple!
Bhargav Ponnapalli
15

Vous trouverez peut-être cela utile:

Si vous souhaitez supprimer toutes les branches qui ne sont pas par exemple 'master', 'foo' et 'bar'

git branch -D `git branch | grep -vE 'master|foo|bar'`

grep -v 'quelque chose' est un matcher avec inversion.

Adi
la source
Personnellement, j'aime l' -Doption comparer à une autre réponse. Merci pour la réponse ici @Adi. Les solutions fonctionnent pour moi.
AMIC MING
9

J'ai mis mes initiales et un tiret (at-) comme les trois premiers caractères du nom de la branche pour cette raison exacte:

git branch -D `git branch --list 'at-*'`
Alan Tweedie
la source
Toutes les réponses disent essentiellement ceci, cela se trouve être le plus simple.
tfantina
7

Si vous n'êtes pas limité à l'utilisation de l'invite de commande git, vous pouvez toujours exécuter git guiet utiliser l'élément de menu Branche-> Supprimer. Sélectionnez toutes les branches que vous souhaitez supprimer et laissez-les déchirer.

Efpophis
la source
cela ne vous permet cependant que de supprimer les branches locales
Stealth Rabbi
7

Solution Powershell:

Si vous exécutez Windows, vous pouvez utiliser PowerShell pour supprimer plusieurs branches à la fois ...

git branch -D ((git branch | Select-String -Pattern '^\s*3\.2\..*') | foreach{$_.ToString().Trim()})
//this will remove all branches starting with 3.2.

git branch -D ((git branch | Select-String -Pattern 'feature-*') | foreach{$_.ToString().Trim()})
// this will delete all branches that contains the word "feature-" as a substring.

Vous pouvez également affiner le fonctionnement de la correspondance de motifs à l'aide de la commande Select-String de Powershell. Jetez un œil aux documents PowerShell .

Imtiaz Shakil Siddique
la source
6

Gardez "développer" et supprimez tous les autres en local

    git branch | grep -v "develop" | xargs git branch -D 
Daniel
la source
5

J'ai créé une petite fonction qui pourrait être utile en fonction de la réponse fournie par @gawi (ci-dessus).

removeBranchesWithPrefix() {
  git for-each-ref --format="%(refname:short)" refs/heads/$1\* | xargs git branch -d
}

Ajoutez cela à votre .bash_profileet redémarrez votre terminal. Ensuite, vous pouvez appeler à partir de la ligne de commande comme ceci:

removeBranchesWithPrefix somePrefix

Remarque

Je l'ai actuellement configuré pour une suppression logicielle, ce qui signifie qu'il ne supprimera pas les branches sauf si elles ont déjà été fusionnées. Si vous aimez vivre sur le bord, changez -den -Det il supprimera tout avec le préfixe!

Logan
la source
5

Si vous avez vraiment besoin de nettoyer toutes vos succursales, essayez

git branch -d $(git branch)

Il supprimera toutes vos succursales fusionnées locales, sauf celle que vous enregistrez actuellement.

C'est un bon moyen de nettoyer votre local

Yulin
la source
Cela a assez bien fonctionné pour moi. Il a laissé deux branches sauf celle dont j'étais une que j'ai ensuite supprimée en utilisant la même commande mais en utilisant un "-D" majuscule au lieu de "-d". J'ai eu quelques erreurs sur git ne trouvant pas de fichiers mais les branches ont été supprimées.
Lurifaxel du
3

Vous aimerez peut-être ce petit article ... Il tire la liste et demande la confirmation de chaque article avant de supprimer enfin toutes les sélections ...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "remove branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done`

Utilisez -D pour forcer les suppressions (comme d'habitude).

Pour plus de lisibilité, voici ce découpé ligne par ligne ...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* |
    while read -r line; do 
        read -p "remove branch: $line (y/N)?" answer </dev/tty;
        case "$answer" in y|Y) echo "$line";; 
        esac; 
    done`

voici l'approche xargs ...

git for-each-ref --format="%(refname:short)" refs/heads/\* |
while read -r line; do 
    read -p "remove branch: $line (y/N)?" answer </dev/tty;
    case "$answer" in 
        y|Y) echo "$line";; 
    esac; 
done | xargs git branch -D

enfin, j'aime avoir ça dans mon .bashrc

alias gitselect='git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "select branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done'

Comme ça je peux juste dire

gitSelect | xargs git branch -D.
Chaos Crafter
la source
3

Pour les âmes pures qui utilisent PowerShell ici le petit script git branch -d $(git branch --list '3.2.*' | %{$_.Trim() })

codevision
la source
2

cela fonctionne correctement pour moi:

git branch | xargs git branch -d

git branch | xargs git branch -D

supprimer toutes les succursales locales

velastiqui
la source
2

Utilisez la commande suivante pour supprimer toutes les branches (la branche extraite ne sera pas supprimée).

git branch | cut -d '*' -f 1 | tr -d " \t\r" | xargs git branch -d

Edit: j'utilise un Mac Os

ILYAS_Kerbal
la source
0

Si vous êtes sous Windows, vous pouvez utiliser PowerShell pour ce faire:

 git branch | grep 'feature/*' |% { git branch -D $_.trim() }

remplacer feature/* par n'importe quel motif que vous aimez.

Mo Valipour
la source
6
grep est une applet de commande non reconnue pour moi ... j'ai donc changé pour cette branche git | où {$ _. Trim (). StartsWith ("bug")} | % {git branch -D $ _. Trim ()} et ça a marché!
Alex
0

Vous pouvez utiliser git guipour supprimer plusieurs branches à la fois. Depuis l'invite de commande / Bash -> git gui-> Distant -> Supprimer la branche ... -> sélectionnez les branches distantes que vous souhaitez supprimer -> Supprimer.

Terry Truong
la source
0

Je viens de nettoyer un grand nombre de succursales locales / distantes obsolètes aujourd'hui.

Voici comment je l'ai fait:

1. répertoriez tous les noms de branche dans un fichier texte:

git branch -a >> BranchNames.txt

2. ajoutez les branches que je veux supprimer pour commander "git branch -D -r":

git branch -D -r origin / dirA / branch01 origin / dirB / branch02 origin / dirC / branch03 (... ajouter n'importe quel nom de branche)

3. exécutez le cmd

Et celui-ci fonctionne tellement plus rapidement et fiable que " git push origin --delete ".

Ce n'est peut-être pas le moyen le plus intelligent comme indiqué dans d'autres réponses, mais celui-ci est assez simple et facile à utiliser.

RainCast
la source
0

Si vous avez installé Git GUI, qui est un module complémentaire par défaut pour Windows, alors c'est le plus simple. Vous pouvez utiliser ctrl pour choisir plusieurs branches et les supprimer en un seul clic.

peiz
la source
0

Si vous utilisez Fish shell, vous pouvez tirer parti des stringfonctions :

git branch -d (git branch -l "<your pattern>" | string trim)

Ce n'est pas très différent des options Powershell dans certaines des autres réponses.

mdiin
la source
0

Si vous aviez toutes les branches à supprimer dans un fichier texte (branches-à-del.txt) (une branche par ligne), vous pouvez le faire pour supprimer toutes ces branches de la télécommande (origine): xargs -a branches-to-del.txt git push --delete origin

code4kix
la source
0

Pour supprimer plusieurs branches en fonction d'un modèle spécifié, procédez comme suit:

Ouvrez le terminal ou équivalent et saisissez les commandes suivantes:

git branch | grep "<pattern>" (preview of the branches based on pattern)

git branch | grep "<pattern>" | xargs git branch -D (replace the <pattern> with a regular expression to match your branch names)

Supprimez toutes les branches 3.2.x, vous devez taper

git branch | grep "3.2" | xargs git branch -D

C'est tout!

Tu es prêt!

Ankit Jindal
la source
-1

Comme dans Git, toutes les branches ne sont rien par référence au .git/refdépôt git, pourquoi ne supprimez-vous pas simplement les branches qui vont et puis si quelque chose est laissé de côté qui n'est pas intéressant dans le référentiel sera automatiquement récupéré pour que vous ne le fassiez pas besoin de déranger.

Debajit
la source
-3

git branch -D <branchName>

Aakash Pahuja
la source
-4

Vous pouvez supprimer toutes les branches en supprimant toutes les références inutiles:

rm .git/refs/heads/3.2.*

Artur Owczarek
la source
2
Downvoted pour deux raisons: 1. il utilise un détail d'implémentation (le fait que les versions actuelles de Git stockent les branches sous forme de fichiers dans un certain répertoire). Cela peut changer dans les futures versions rendant la réponse invalide. 2. Cela ne fonctionne pas si le référentiel se trouve dans un répertoire séparé .
axiac
En outre, cela produit des résultats très inattendus si vous l'exécutez sur un référentiel compressé ( git gc). Ne fais pas ça.
Matthieu Moy