Comment tailler les branches de suivi local qui n'existent plus sur distant

Avec git remote prune origin Je peux supprimer les branches locales qui ne sont plus sur la télécommande.

Mais je veux aussi supprimer les branches locales qui ont été créées à partir de ces branches distantes (vérifier si elles sont non fusionnées serait bien).

Comment puis-je faire cela?

456
git
demandé sur mc_kaiser 2012-10-25 12:31:13

24 réponses

Après l'élagage, vous pouvez obtenir la liste des branches distantes avec git branch -r. La liste des branches avec leur branche de suivi à distance peut être récupérée avec git branch -vv. Donc, en utilisant ces deux listes, vous pouvez trouver les branches de suivi à distance qui ne sont pas dans la liste des télécommandes.

Cette ligne devrait faire l'affaire (nécessite bash ou zsh, ne fonctionnera pas avec la norme Bourne shell):

git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d

Cette chaîne obtient la liste des branches distantes et la passe dans egrep via la norme entrée. Et filtre les branches qui ont une branche de suivi à distance (en utilisant git branch -vv et en filtrant pour celles qui ont origin) puis en obtenant la première colonne de cette sortie qui sera le nom de la branche. Enfin passer tous les noms de branche dans la commande delete branch.

Comme il utilise l'option -d, il ne supprimera pas les branches qui n'ont pas été fusionnées dans la branche sur laquelle vous vous trouvez lorsque vous exécutez cette commande.

Rappelez-vous également que vous devrez exécuter git fetch --prune d'abord , sinon {[0] } verra toujours les branches distantes.

563
répondu Schleis 2016-10-24 12:09:57

Si vous souhaitez supprimer toutes les branches locales déjà fusionnées dans master, vous pouvez utiliser la commande suivante:

git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d

Plus d'infos .

287
répondu jackocnr 2017-10-10 11:47:48

Parmi les informations présentées par git help fetch, il y a ce petit article:

 -p, --prune
        After fetching, remove any remote-tracking branches which no longer exist on the remote.

Alors, peut-être, git fetch -p est ce que vous recherchez?

EDIT: Ok, pour ceux qui débattent encore de cette réponse 3 ans après le fait, voici un peu plus d'informations sur pourquoi j'ai présenté cette réponse...

Tout d'abord, L'OP dit qu'ils veulent "supprimer également les branches locales qui ont été créées à partir de ces branches distantes [qui ne sont plus sur la télécommande]". Ce n'est pas sans ambiguïté possible dans git. Voici un exemple.

Disons que j'ai une pension sur un serveur central, et il a deux branches, appelé A et B. Si je clone ce repo sur mon système local, mon clone aura des refs locaux (pas encore de branches réelles) appelés origin/A et origin/B. Maintenant, disons que je fais ce qui suit:

git checkout -b A origin/A
git checkout -b Z origin/B
git checkout -b C <some hash>

Les faits pertinents ici sont que j'ai choisi pour une raison quelconque de créer une branche sur mon repo local qui a un nom différent de son origine, et j'ai aussi une branche locale qui ne le fait pas (encore) existe sur le repo d'origine.

Disons maintenant que je supprime à la fois les branches A et B sur le repo distant et met à jour mon repo local (git fetch d'une certaine forme), ce qui fait disparaître mes refs locaux origin/A et origin/B. Maintenant, mon repo local a trois branches encore, A, Z, et C. Aucun d'entre eux n'a de branche correspondante sur le repo distant. Deux d'entre eux ont été "créés à partir ... les branches distantes", mais même si je sais qu'il y a une branche appelée B sur l'origine, je n'ai aucun moyen pour savoir que Z a été créé à partir de B, car il a été renommé dans le processus, probablement pour une bonne raison. Donc, vraiment, sans un processus externe d'enregistrement des métadonnées d'origine de branche, ou un humain qui connaît l'histoire, il est impossible de dire laquelle des trois branches, le cas échéant, l'OP vise pour la suppression. Sans certaines informations externes que git ne maintient pas automatiquement pour vous, git fetch -p est à peu près aussi proche que vous pouvez obtenir, et toute méthode automatique pour littéralement tenter quoi le PO demandé court le risque de supprimer trop de branches, ou d'en manquer certaines que le PO voudrait autrement supprimer.

Il y a aussi d'autres scénarios, comme si je crée trois branches distinctes sur origin/A pour tester trois approches différentes de quelque chose, puis origin/A s'en va. Maintenant, j'ai trois branches, qui ne peuvent évidemment pas toutes correspondre au nom, mais elles ont été créées à partir de origin/A, et donc une interprétation littérale de la question OPs nécessiterait de supprimer les trois. Cependant, cela peut ne pas être souhaitable, si vous pouviez même trouver un moyen fiable de les faire correspondre...

109
répondu twalberg 2017-06-12 16:21:08

Cela supprimera les branches locales pour lesquelles les branches de suivi à distance ont été élaguées. (Assurez-vous que vous êtes sur master branche!)

git checkout master
git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -d

Détails:

  • git branch -vv affiche "disparu" pour les branches locales que la télécommande a été élaguée.

    mybranch abc1234 [origin/mybranch: gone] commit comments
    
  • -d vérifiera s'il a été fusionné (-D le supprimera indépendamment)

    error: The branch 'mybranch' is not fully merged.
    
84
répondu wisbucky 2017-05-31 17:55:01

On peut configurer Git pour supprimer automatiquement les références aux branches distantes supprimées lors de la récupération:

git config --global fetch.prune true

Lorsque vous appelez git fetch ou git pull par la suite, les références aux branches distantes supprimées sont automatiquement supprimées.

37
répondu wedesoft 2017-01-12 11:09:16

Il y a un paquet npm soigné qui le fait pour vous (et il devrait fonctionner multi-plateforme).

Installez-le avec: npm install -g git-removed-branches

Puis git removed-branches vous montrera toutes les branches locales périmées, et git removed-branches --prune pour les supprimer réellement.

Plus d'infos ici.

18
répondu tzachs 2017-08-15 18:41:58

Il répertorie les branches locales dont la branche de suivi à distance est supprimée de la télécommande

$ git remote prune origin --dry-run

Si vous voulez dé-référencer ces branches locales de local qui ne sont pas suivies

$ git remote prune origin
15
répondu 027 2016-02-03 08:43:58

Si vous utilisez Windows et Powershell, vous pouvez utiliser ce qui suit pour supprimer toutes les branches locales qui ont été fusionnées dans la branche actuellement extraite:

git branch --merged | ? {$_[0] -ne '*'} | % {$_.trim()} | % {git branch -d $_}

Explication

  • répertorie la branche actuelle et les branches qui y ont été fusionnées
  • Filtre la branche courante
  • nettoie tous les espaces de début ou de fin de la sortie git pour chaque nom de branche restant
  • supprime les branches locales fusionnées

Ça vaut le coup courir git branch --merged par lui-même d'abord juste pour s'assurer qu'il va seulement supprimer ce que vous attendez de lui.

(porté/automatisé à partir de http://railsware.com/blog/2014/08/11/git-housekeeping-tutorial-clean-up-outdated-branches-in-local-and-remote-repositories/.)

11
répondu Gnat 2017-04-10 22:57:01

Solution Windows

Pour Microsoft Windows Powershell:

git checkout master; git remote update origin --prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Split(" ")[0]} | % {git branch -d $_}

Explication

git checkout master passe à la branche maître

git remote update origin --prune pruneaux branches distantes

git branch -vv obtient une sortie détaillée de toutes les branches (git de référence)

Select-String -Pattern ": gone]" obtient uniquement les enregistrements où ils ont été supprimés de la télécommande.

% { $_.toString().Split(" ")[0]} obtenir le nom de la branche

% {git branch -d $_} supprime la branche

6
répondu chris31389 2018-03-01 09:59:09

Je ne sais pas comment tout faire en même temps, mais git git branch -d <branchname> ne supprimera une branche locale que si elle est complètement fusionnée. Notez les minuscules D.

git branch -D <branchname> (Remarque Le capital D) supprimera une succursale locale quel que soit son statut fusionné.

4
répondu NHDaly 2012-10-25 08:35:25

Je voulais quelque chose qui purgerait toutes les branches locales qui suivaient une branche distante, sur origin, où la branche distante a été supprimée (gone). Je ne voulais pas supprimer les branches locales qui n'ont jamais été configurées pour suivre une branche distante (c'est-à-dire: mes branches de développement locales). En outre, je voulais un simple one-liner qui utilise simplement git, ou d'autres outils CLI simples, plutôt que d'écrire des scripts personnalisés. J'ai fini par utiliser un peu de grep et awk pour faire cette commande simple, puis l'ai ajouté comme alias dans mon ~/.gitconfig.

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

Voici une commande 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'

Remarque: L'utilisation de l'indicateur -D à git branch peut être très dangereuse. Donc, dans la commande config ci-dessus, j'utilise l'option -d pour git branch plutôt que -D; j'utilise -D dans ma configuration réelle. J'utilise -D parce que je ne veux pas entendre Git se plaindre des branches non fusionnées, je veux juste qu'elles disparaissent. Vous pouvez également vouloir cette fonctionnalité. Si c'est le cas, utilisez simplement -D au lieu de -d à la fin de cette commande de configuration.

4
répondu Karl Wilbur 2018-03-26 12:38:17

Encore plus court et plus sûr one-liner:

git branch -d $(git branch --merged | cut -c 3-)

Assurez-vous de commander à la branche qui n'est pas encore fusionnée, avant de l'exécuter. Parce que vous ne pouvez pas supprimer la branche que vous êtes actuellement enregistré.

3
répondu FelikZ 2015-07-30 09:31:13

Sur la base des réponses ci-dessus, je suis venu avec cette solution d'une ligne:

git remote prune origin; git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d
2
répondu gagarwal 2015-08-15 02:58:03

En utilisant une variante sur la réponse de @wisbucky, j'ai ajouté ce qui suit en tant qu'alias à mon fichier ~/.gitconfig:

pruneitgood = "!f() { \
    git remote prune origin; \
    git branch -vv | perl -nae 'system(qw(git branch -d), $F[0]) if $F[3] eq q{gone]}'; \
}; f"

Avec cela, un simple git pruneitgood nettoiera les deux branches locales et distantes qui ne sont plus nécessaires après les fusions.

2
répondu Ken Williams 2016-11-11 18:56:23

Vous pouvez utiliser cette commande:

git branch --merged master | grep -v "\* master" | xargs -n 1 git branch -d

Git Clean: supprime les Branches déjà fusionnées y compris la décomposition de la commande

2
répondu sendon1982 2018-06-13 00:34:41

La variante de Schleis ne fonctionne pas pour moi (Ubuntu 12.04), alors laissez-moi proposer mes variantes (claires et brillantes:):

Variante 1 (je préférerais cette option):

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

Variante 2:

A. essai à sec:

comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | awk '{print "git branch -D " $1}'

B. supprimer les branches:

comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | xargs git branch -D
1
répondu daniilyar 2014-07-23 12:38:56

J'ai transformé la réponse acceptée en un script robuste. Vous le trouverez dans mon dépôt git-extensions .

$ git-prune --help
Remove old local branches that do not exist in <remote> any more.
With --test, only print which local branches would be deleted.
Usage: git-prune [-t|--test|-f|--force] <remote>
1
répondu Ingo Karkat 2016-09-22 12:19:38

Voici une adaptation de la réponse de @ wisbucky pour les utilisateurs de Windows:

for /f "tokens=1" %i in ('git branch -vv ^| findstr ": gone]"') DO git branch %i -d

J'utilise posh-Git et malheureusement PS n'aime pas le naked for, alors j'ai créé un script de commande ol simple nommé PruneOrphanBranches.cmd:

@ECHO OFF
for /f "tokens=1" %%i in ('git branch -vv ^| findstr ": gone]"') DO CALL :ProcessBranch %%i %1

GOTO :EOF

:ProcessBranch
IF /I "%2%"=="-d" (
    git branch %1 %2
) ELSE (
    CALL :OutputMessage %1
)
GOTO :EOF

:OutputMessage
ECHO Will delete branch [%1] 
GOTO :EOF

:EOF

Appelez-le sans paramètres pour voir une liste, puis appelez-le avec "- d "pour effectuer la suppression réelle ou" - D " pour toutes les branches qui ne sont pas complètement fusionnées mais que vous voulez supprimer de toute façon.

1
répondu Sam C 2016-11-16 20:16:14

Essayez ceci dans git bash, pour récupérer et élaguer les références aux branches supprimées, puis élaguer les branches locales qui suivaient celles supprimées:

git fetch -p && git branch -d `git branch -vv | grep ': gone]' | awk '{print $1}' | xargs`

N'oubliez pas de commander d'abord une branche qui ne sera pas supprimée, de sorte que cela ne bloque pas la suppression de la branche.

1
répondu Guillermo Gutiérrez 2016-11-24 14:57:27

La version Powershell de git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d

git branch --merged master | %{ if($_ -notmatch '\*.*master'){ git branch -d "$($_.Trim())" }}

Cela supprimera toutes les branches locales qui ont été fusionnées dans master, pendant que vous êtes sur la branche master .

git checkout master pour passer.

1
répondu Kevin George 2018-07-18 15:28:10

Sur la base des réponses ci-dessus, j'utilise ce liner plus court:

git remote prune origin | grep pruned | awk 'BEGIN{FS="/"} ; { print $2 }' | xargs git branch -d
0
répondu hidralisk 2018-09-20 19:24:08

Supprime toute branche qui n'est pas à jour avec master

git co master && git branch | sed s/\*/\ / | xargs git branch -d 2> /dev/null
-2
répondu Jason Waldrip 2014-10-21 06:08:46

Je suis sûr que git remote prune origin est ce que vous voulez.

Vous pouvez l'exécuter comme git remote prune origin --dry-run pour voir ce queferait sans apporter de modifications.

-4
répondu Jason Antman 2014-05-09 01:56:36

Utilisation de L'interface graphique? Procédure manuelle, mais rapide et facile.

$ git gui

Sélectionnez "Branche - > Supprimer". Vous pouvez sélectionner plusieurs branches avec ctrl-click (windows) et les supprimer toutes.

-12
répondu Pedro Ballesteros 2014-12-04 11:36:58