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.

38voto

cs01 Points 2100

Supprimez toutes les branches qui ont été fusionnées dans master, mais n'essayez pas de supprimer master lui-même :

git checkout master && git pull origin master && git fetch -p && git branch -d $(git branch --merged | grep master -v)

ou ajouter un alias :

alias gitcleanlocal="git checkout master && git pull origin master && git fetch -p && git branch -d $(git branch --merged | grep master -v)"

Explication :

git checkout master checkout branche master

git pull origin master s'assurer que toutes les modifications à distance ont été fusionnées dans la branche locale

git fetch -p supprimer les références aux branches distantes qui ont été supprimées

git branch -d $(git branch master --merged | grep master -v) supprimer toutes les branches qui ont été fusionnées dans master, mais ne pas essayer de supprimer master lui-même

33voto

ckirksey3 Points 40
git fetch -p

Cela permettra pruneau toutes les branches qui n'existent plus sur le site distant.

94 votes

Cela supprime les références distantes, mais pas les branches locales elles-mêmes. Bien que cette commande soit utile, je ne pense pas qu'elle réponde à la question de l'OP.

1 votes

Quoi ? Cela supprime les branches locales pour moi.

2 votes

@AlexHall Le référentiel distant a une branche X ; vous git checkout X Maintenant, votre dépôt a une branche de suivi (locale). X et une branche distante origin/X ; le référentiel distant supprime X ; vous git fetch-p ; dans votre référentiel local, non seulement origin/X mais aussi X ont été supprimés. C'est ce que vous dites ?

31voto

Himura Points 1

Encore une autre réponse, parce qu'aucune des solutions ne répond à mes besoins en matière d'élégance et de multiplateforme :

Commande pour supprimer les branches locales pas sur le distant :

for b in $(git for-each-ref --format='%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)' refs/heads); do git branch -d $b; done

Pour l'intégrer à gitconfig afin qu'il puisse être exécuté avec git branch-prune :

Bash

git config --global alias.branch-prune '!git fetch -p && for b in $(git for-each-ref --format='\''%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)'\'' refs/heads); do git branch -d $b; done'

PowerShell

git config --global alias.branch-prune '!git fetch -p && for b in $(git for-each-ref --format=''%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)'' refs/heads); do git branch -d $b; done'

(Besoin d'aide pour trouver une commande universelle pour PowerShell et bash)

Pourquoi cette réponse est-elle la meilleure ?

  • Offre une solution complète : ajoute un git branch-prune à votre git
  • Fonctionne bien à partir de Windows PowerShell
  • L'idée centrale est la suivante @jason.rickman 's méthode éprouvée en utilisant git for-each-ref
  • L'analyse syntaxique et le filtrage sont effectués avec --filter donc pas de dépendances externes nécessaires

Explication :

  • Ajoute un nouvel alias à votre ~\.gitconfig . Après avoir exécuté ceci, vous pouvez simplement faire git branch-prune
  • Dans cet alias :
    • Récupère les branches avec l'option --prune qui "supprime les branches de suivi à distance qui ne sont plus sur les sites distants".
    • Utilisations git for-each-ref y --filter pour obtenir une liste des branches sont [gone] (sans télécommande)
    • Boucle à travers cette liste et supprime la branche en toute sécurité

25voto

Pranav Kasetti Points 2072

Alors que les réponses ci-dessus couvrent la façon d'élaguer les branches manuellement, cette réponse ajoute l'automatisation pour résoudre ce problème. git dispose maintenant d'un nouveau paramètre pour élaguer les branches périmées qui ne sont plus sur la télécommande pour chaque action de récupération. C'est une bonne chose car nous n'avons plus besoin d'appeler manuellement remote prune chaque fois que nous supprimons des branches ( git pull appelle également git fetch ).

Activer le comportement d'élagage pour chaque recherche (fetch)

Pour activer cette fonction dans la configuration globale :

git config --global fetch.prune true

Le fait de rendre la chose automatique signifie que vous pouvez oublier d'ajouter ce paramètre sur les nouvelles machines. Cela fonctionne tout simplement.

Activer le comportement d'élagage pour chaque récupération sur des postes distants spécifiques.

git config --global remote.<name>.prune true

Elagage local automatisé

Nous pouvons appliquer la même commande pour l'élagage local sans l'ajout de la touche --global drapeau.

.gitconfig

Les commandes ci-dessus s'appliquent au système global et au système local. .gitconfig comme suit :

...
[fetch]
    prune = true

Je peux recommander d'ajouter ceci à une configuration ansible ou à votre dépôt dotfiles ( .gitconfig ) pour automatiser la configuration à l'avenir.

Le paramètre de configuration appelle la commande ci-dessous à chaque récupération :

git remote prune <remote name>

Résumé

Pour élaguer les références dans le cadre de votre flux de travail normal sans avoir besoin de vous rappeler de lancer cette opération, définissez fetch.prune au niveau mondial ou remote.<name>.prune per-remote dans la configuration. Voir git-config .

19voto

bxm Points 384

Encore une autre réponse pour le tas, s'inspirant fortement de La réponse de Patrick (ce qui me plaît parce que cela semble supprimer toute ambiguïté sur l'endroit où se trouvent les gone] correspondront dans le git branch ), mais en ajoutant un aspect *nix.

Dans sa forme la plus simple :

git branch --list --format \
  "%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)" \
  | xargs git branch -D

Je l'ai emballé dans un git-gone script sur mon chemin :

#!/usr/bin/env bash

action() {
  ${DELETE} && xargs git branch -D || cat
}

get_gone() {
  git branch --list --format \
    "%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)"
}

main() {
  DELETE=false
  while [ $# -gt 0 ] ; do
    case "${1}" in
      (-[dD] | --delete) DELETE=true ;;
    esac
    shift
  done
  get_gone | action
}

main "${@}"

NB - Le --format semble être assez récente ; j'ai dû mettre à jour git de 2.10.quelque chose à 2.16.3 pour l'obtenir.

EDIT : modifié pour inclure la suggestion sur refname:short de Benjamin W.

NB2 - Je n'ai testé qu'en bash d'où le hashbang, mais probablement portable à sh .

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