1862 votes

Supprimer le suivi des branches qui ne sont plus sur la télécommande

Existe-t-il un moyen simple de supprimer toutes les branches de suivi dont l'équivalent distant n'existe plus ?

Exemple :

Branches (locales et distantes)

  • maître
  • origine/maître
  • origine/bug-fix-a
  • origine/bug-fix-b
  • origine/bug-fix-c

Localement, je n'ai qu'une branche master. Maintenant, je dois travailler sur Correction de bogues - alors je le vérifie, je travaille dessus et j'envoie les changements à la télécommande. Ensuite, je fais la même chose avec bug-fix-b .

Branches (locales et distantes)

  • maître
  • Correction de bogues -
  • bug-fix-b
  • origine/maître
  • origine/bug-fix-a
  • origine/bug-fix-b
  • origine/bug-fix-c

Maintenant, j'ai des succursales locales maître , Correction de bogues - , bug-fix-b . Le responsable de la branche Master va fusionner mes modifications dans maître et supprimer toutes les branches qu'il a déjà fusionnées.

L'état actuel est donc maintenant :

Branches (locales et distantes)

  • maître
  • Correction de bogues -
  • bug-fix-b
  • origine/maître
  • origine/bug-fix-c

Maintenant je voudrais appeler une commande pour supprimer les branches (dans ce cas-ci Correction de bogues - , bug-fix-b ), qui ne sont plus représentés dans le référentiel distant.

Ce serait quelque chose comme la commande existante git remote prune origin mais plutôt git local prune origin .

25 votes

Question très bien formulée avec un exemple très clair. Excellent travail !

3 votes

Pourquoi la majorité des réponses répondent : "Supprimer les branches qui ont été fusionnées", alors que la question porte spécifiquement sur les "branches qui ne sont plus sur la télécommande". C'est une différence assez importante.

16voto

pabloa98 Points 371

Cela supprimera toutes les branches locales fusionnées, sauf la référence maître locale et celle qui est actuellement utilisée :

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

Et cela supprimera toutes les branches ayant déjà été supprimées du référentiel distant référencé par " origine ", mais sont toujours disponibles localement en " remotes/origine ".

git remote prune origin

15voto

Mark Longair Points 93104

Je ne pense pas qu'il y ait une commande intégrée pour faire cela, mais il est sûr de faire ce qui suit :

git checkout master
git branch -d bug-fix-a

Lorsque vous utilisez -d git refusera de supprimer la branche à moins qu'elle ne soit complètement fusionnée dans HEAD ou sa branche amont de suivi à distance. Ainsi, vous pouvez toujours boucler sur la sortie de git for-each-ref et essayer de supprimer chaque branche. Le problème avec cette approche est que je soupçonne que vous ne voulez probablement pas bug-fix-d pour être supprimé juste parce que origin/bug-fix-d contient son histoire. Au lieu de cela, vous pourriez créer un script quelque chose comme ce qui suit :

#!/bin/sh

git checkout master &&
for r in $(git for-each-ref refs/heads --format='%(refname:short)')
do
  if [ x$(git merge-base master "$r") = x$(git rev-parse --verify "$r") ]
  then
    if [ "$r" != "master" ]
    then
      git branch -d "$r"
    fi
  fi
done

Avertissement : Je n'ai pas testé ce script - à utiliser avec précaution...

0 votes

J'ai pris la liberté de modifier le script. Cela ne donne toujours pas de garanties, mais cela fonctionne et semble fonctionner maintenant.

15voto

Francois Points 2397

Cela pourrait être utile à certains, une simple ligne pour effacer toutes les branches locales, sauf master et develop.

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

11voto

Karl Wilbur Points 3089

Rien de tout cela ne me convenait vraiment. Je voulais quelque chose qui purge 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 (par exemple, mes branches de développement locales). De plus, je voulais une ligne simple 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 y awk pour réaliser cette commande simple.

C'est finalement ce qui s'est retrouvé dans 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 : Dans la commande de configuration, j'utilise l'option -d option pour git branch plutôt que -D comme je le fais dans ma configuration actuelle. J'utilise -D parce que je ne veux pas entendre Git se plaindre de branches non immergées. Vous pouvez aussi vouloir cette fonctionnalité. Dans ce cas, utilisez simplement -D au lieu de -d à la fin de cette commande de configuration.

10voto

Pxtl Points 662

Solution basée sur Powershell que je trouve plus lisible que beaucoup des implémentations ici.

# prune deleted remoted branches
git fetch -p

# get all branches and their corresponding remote status
# deleted remotes will be marked [gone]
git branch -v |
  #find ones marked [gone], capture branchName
  select-string -Pattern '^  (?<branchName>\S+)\s+\w+ \[gone\]' | 
  foreach-object{ 
     #delete the captured branchname.
     git branch -D $_.Matches[0].Groups['branchName']
  }

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