Git: Supprimer toutes les branches qui ne sont plus sur le dépôt distant

Quand on bosse en équipe sur un projet, on finit par accumuler pas mal de branches sur notre dépôt local qui ont étés supprimées du remote suite à des merge de PR.

Si vous êtes comme moi, vous aimez bien les choses simples et avoir un dépôt local relativement clean. C’est plus facile de s’y retrouver parmi une petite dizaine de branches qu’avec des centaines de vielles branches obsolètes.
Et si vous êtes aussi comme moi, vous avez la flemme de faire le nettoyage à la main à chaque fois que ça devient trop le bordel.

Par où commencer ?

Dans git, on n’a pas de commande toute faite pour nettoyer les branches. Il va donc falloir trouver une astuce pour savoir si une branche qu’on a sur notre dépôt local est toujours sur le remote.

La première étape est de mettre à jour les références locales avec l’état du distant avec git fetch -p

L’option -p permet de flagger les branches locales qui ne sont plus sur le remote comme supprimées. Mais cela ne suffit pas. Git ne vas pas supprimer automatiquement des branches sans demande explicite de votre part.

Où trouver l’information ?

Avec la commande git for-each-ref on peut parcourir toutes les références de notre dépôt local. Avec un peu de formatage (upstream:track), on peut récupérer un truc assez intéressant :

>git for-each-ref --format '%(refname) %(upstream:track)' refs/heads

refs/heads/feature-1[gone]
refs/heads/feature-2[gone]
refs/heads/feature-3[gone]
refs/heads/feature-4[gone]
refs/heads/feature-5
refs/heads/feature-6[behing 5]
refs/heads/feature-7[ahead 3]

On peut voir que les branches présentes en local mais plus sur le remote sont marquées avec :gone

On remarque aussi que les branches ayant des commits en local mais pas encore push sur le remote sont marquées ahead. Ainsi que celles ayant des commits sur le remote pas encore pull sont marquées behind.

Construire une commande

Avec ces informations, on va maintenant pouvoir construire un petit script pour nettoyer les branches orphelines !

On va donc créer un fichier gitclean.sh dans notre dossier perso bin :

>cd ~/bin
>nano gitclean.sh

Et y ajouter le script suivant

git fetch -p && 
for branch in $(git for-each-ref --format '%(refname) %(upstream:track)' refs/heads | awk '$2 == "[gone]" {sub("refs/heads/", "", $1); print $1}'); 
do git branch -D $branch; 
done

Enregistrer et redémarrer le terminal pour que le path soit rechargé, puis tester.

Tester la suppression

C’est le moment de vérité, on va lancer la commande et comparer la liste des branches avec ce qu’on avait avant :

>cd chemin/vers/mon-projet-git
>gitclean.sh
Deleted branch feature-1 (was cae24282)
Deleted branch feature-2 (was bc122181)
Deleted branch feature-3 (was f372e4ca)
Deleted branch feature-4 (was ca77de30)

Si quelque chose de similaire s’affiche, c’est gagné ! Maintenant quand on lance la commande git branch on doit avoir quelque chose dans ce genre :

  feature-5
  feature-6
* feature-7

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *