- Une commande simple pour résoudre l’ancien problème de nettoyage des branches Git a été retrouvée dans une documentation interne de développement de la CIA
git branch --merged | grep -v "\*\|master" | xargs -n 1 git branch -d
- La commande supprime en lot les branches fusionnées en excluant la branche actuelle et master des résultats de
git branch --merged
- Il existe aussi une version adaptée aux projets modernes, qui exclut les branches
main et develop
- On peut l’enregistrer comme alias Git pour automatiser une tâche répétitive ; c’est un outil simple mais utile pour améliorer durablement l’efficacité et garder un dépôt bien rangé
Une astuce Git découverte dans Vault7
- Les documents Vault7 publiés par WikiLeaks en 2017 contenaient des outils de piratage de la CIA ainsi que de la documentation interne de développement
- L’une des pages proposait une collection d’astuces et de tricks Git, dont la plupart relevaient d’usages classiques comme la modification de commits, le stash ou
bisect
- La commande en une ligne trouvée dans ce document est restée dans mon
~/.zshrc jusqu’à aujourd’hui
Le vieux problème du nettoyage des branches
- Dans un dépôt Git local, les branches fusionnées s’accumulent avec le temps et deviennent difficiles à gérer
- Branches de fonctionnalité, hotfixes ou branches d’expérimentation restent souvent après fusion, ce qui encombre la sortie de
git branch
- La commande
git branch --merged permet d’identifier les branches fusionnées, mais leur suppression manuelle est fastidieuse
La commande d’origine du document de la CIA
Version modernisée de la commande
- Comme la plupart des projets utilisent désormais la branche
main, on peut modifier la commande comme suit
git branch --merged origin/main | grep -vE "^\s*(\*|main|develop)" | xargs -n 1 git branch -d
- Après exécution depuis la branche
main après déploiement, des dizaines de branches peuvent être réduites à quelques-unes
- Cette commande peut être enregistrée comme alias Git pour être lancée plus facilement
alias ciaclean='git branch --merged origin/main | grep -vE "^\s*(\*|main|develop)" | xargs -n 1 git branch -d'
- Ensuite, il suffit de saisir
ciaclean dans le dépôt pour lancer automatiquement le nettoyage
Efficacité et aspect pratique
- Cette commande permet de gagner quelques minutes chaque semaine et d’avoir une liste de branches propre
- Simple, mais considérée comme un outil pratique offrant un gain de productivité continu
4 commentaires
Dans les commentaires HN, il y a quelqu’un qui dit utiliser un programme que j’avais créé.
> J’utilise git-trim pour ça :
> https://github.com/foriequal0/git-trim
> Le README explique aussi pourquoi c’est mieux qu’un one-liner bash dans certains cas.
> https://news.ycombinator.com/item?id=47089533
J’utilise moi aussi un alias
git gone. C’est très pratique. - alias.gone = ! git fetch -p && git for-each-ref --format '%(refname:short) %(upstream:track)' | awk '$2 == "[gone]" {print $1}' | xargs -r git branch -DJe n’utilise pas git pur, mais j’utilise un outil appelé gh-poi pour faire le nettoyage.
https://github.com/seachicken/gh-poi
Avis Hacker News
J’utilise un alias
git tidypour nettoyer les branchesIl ne supprime pas les branches par défaut (main, master) et ne touche ni à la branche courante ni aux branches d’autres worktree
Les branches disparues du dépôt distant sont aussi supprimées automatiquement, et le code se trouve dans ma configuration dotfiles
init.defaultBranchest risqué. Le nom de la branche par défaut peut varier selon les dépôts, et ce réglage est global, donc il faut le définir à l’avanceJ’ai créé un alias
git defaultpour détecter automatiquement la vraie branche par défaut sur le dépôt distantoriginJ’utilise une commande de nettoyage intégrée à
fzfElle permet de présélectionner les branches fusionnées pour les supprimer d’un coup, avec la possibilité d’en exclure certaines si besoin
Elle nettoie aussi les branches distantes, et le code se trouve dans ma configuration .gitconfig
J’utilise aussi la variable
user.primaryBranchpour définir une branche par défaut différente selon le dépôtinit.defaultBranchne suffirait pas. Même sur un dépôt déjà initialisé, ça fonctionne avecgit config --local init.defaultBranch maingit pull origin main:main, puisgit rebase maingit branch --mergedne fonctionne pas correctement dans les dépôts qui utilisent le squash mergeParce que le SHA du commit squashé diffère du HEAD de la branche d’origine
Je me demande s’il existe un outil capable de détecter de façon fiable les branches squashées
Ce n’est pas parfait, mais c’est suffisamment pratique, et il y a toujours une demande de confirmation avant suppression
Je me suis inspiré du réglage de suppression automatique des branches de GitHub
La plupart des gens gèrent ça en se branchant sur l’événement de suppression de branche distante
J’utilise un alias
git gonequi fait ungit fetch -ppuis nettoie les branches en état[gone]J’utilise donc un script qui combine
git branch --merged,git cherryetgit log grepEn revanche, il peut y avoir des faux positifs si des commits ont été amendés ou s’il y en a plusieurs
J’utilise un alias
git lintpour nettoyer les branches fusionnéesIl exclut main, master et stable de la suppression, et j’utilise souvent la combinaison
git pull --prune && git lintLa commande Git elle-même est banale, mais je trouvais amusant d’être tombé sur un document provenant de Wikileaks en cliquant
Le projet “Fine Dining” de la CIA était un outil servant à déguiser des malwares cachés sur une clé USB en applications ordinaires
À l’origine, le problème pouvait aussi se résoudre simplement en affichant la liste des branches non fusionnées
C’est étrange qu’une tâche aussi naturelle demande plusieurs lignes de bash
Vu la taille du code de Git, c’est dommage que ce ne soit pas proposé en fonctionnalité native
Voir aussi ce billet de blog
xargsou les boucles for, ce genre de chose devient trivialEn faire une commande intégrée impliquerait de gérer toutes sortes de cas particuliers, ce qui pourrait au contraire la complexifier
Au final, certains ont réagi par un « on dirait quelqu’un qui vient juste d’apprendre
xargs»Moi aussi, j’ai appris ce genre de choses grâce à des blogs et des articles
xargs, c’est déjà une bonne chose en soiEn ce moment, je suis accro aux TUI. Dès qu’un truc me gêne, je demande à Claude-code de me créer un TUI
J’ai créé avec la bibliothèque Textual un TUI pour gérer les Git worktree, et Claude se débrouille plutôt bien en Python
tig, un ancien TUI Git. C’est une bonne source d’inspirationOn peut aussi lire cet article sur la fonctionnalité de rebase de Magit
J’ai implémenté quelque chose de similaire dans Fish shell
C’est une fonction qui permet, avec
fzf, de sélectionner puis supprimer des branches disparues du distantLe code est dans mes dotfiles