26 points par GN⁺ 2026-02-21 | 4 commentaires | Partager sur WhatsApp
  • 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

  • La commande d’origine proposée était la suivante
    git branch --merged | grep -v "\*\|master" | xargs -n 1 git branch -d  
    
  • Explication des composants
    • git branch --merged : affiche la liste de toutes les branches locales fusionnées dans la branche actuelle
    • grep -v "\*\|master" : exclut la branche actuelle (*) et master
    • xargs -n 1 git branch -d : supprime en toute sécurité les branches restantes une par une (-d ne supprime pas les branches non fusionnées)

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

 
foriequal0 2026-02-21

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

 
youngminz 2026-02-21

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 -D

 
a1eng0 2026-02-21

Je n’utilise pas git pur, mais j’utilise un outil appelé gh-poi pour faire le nettoyage.

https://github.com/seachicken/gh-poi

 
GN⁺ 2026-02-21
Avis Hacker News
  • J’utilise un alias git tidy pour nettoyer les branches
    Il 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

    • Utiliser init.defaultBranch est 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’avance
      J’ai créé un alias git default pour détecter automatiquement la vraie branche par défaut sur le dépôt distant origin
    • Ce script est vraiment utile, ce serait bien de le proposer à git extras
  • J’utilise une commande de nettoyage intégrée à fzf
    Elle 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.primaryBranch pour définir une branche par défaut différente selon le dépôt

    • Je me demande si init.defaultBranch ne suffirait pas. Même sur un dépôt déjà initialisé, ça fonctionne avec git config --local init.defaultBranch main
    • On peut faire un pull depuis une autre branche sans changer de branche. Par exemple avec git pull origin main:main, puis git rebase main
  • git branch --merged ne fonctionne pas correctement dans les dépôts qui utilisent le squash merge
    Parce 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

    • J’ai récemment modifié mon script pour ne supprimer que les branches qui n’ont eu aucun commit depuis 30 jours et qui n’existent plus sur le distant
      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
    • Ce n’est pas seulement le squash merge : les rebase merge non plus ne sont pas détectés
      La plupart des gens gèrent ça en se branchant sur l’événement de suppression de branche distante
    • Moi, je supprime simplement la branche locale quand la branche distante a disparu
      J’utilise un alias git gone qui fait un git fetch -p puis nettoie les branches en état [gone]
    • Je travaille dans un environnement avec Gerrit, donc le rebase se fait côté serveur
      J’utilise donc un script qui combine git branch --merged, git cherry et git log grep
      En revanche, il peut y avoir des faux positifs si des commits ont été amendés ou s’il y en a plusieurs
    • On pourrait peut-être détecter une branche vide en essayant d’abord un rebase sur cette branche
  • J’utilise un alias git lint pour nettoyer les branches fusionnées
    Il exclut main, master et stable de la suppression, et j’utilise souvent la combinaison git pull --prune && git lint

  • La 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

    • Ça ressemble plutôt à une technique d’espionnage assez classique. Le vrai truc “dingue”, c’étaient des expériences comme MKULTRA, où ils administraient du LSD à des gens à leur insu
  • À 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

    • Mais dès qu’on apprend un peu xargs ou les boucles for, ce genre de chose devient trivial
      En faire une commande intégrée impliquerait de gérer toutes sortes de cas particuliers, ce qui pourrait au contraire la complexifier
    • Évaluer ce genre de chose au “nombre de lignes de code” me paraît être un critère assez étrange
  • Au final, certains ont réagi par un « on dirait quelqu’un qui vient juste d’apprendre xargs »

    • Cette attitude donne une impression de gatekeeping. Partager quelque chose qu’on vient d’apprendre, c’est très bien
      Moi aussi, j’ai appris ce genre de choses grâce à des blogs et des articles
    • Mais le fait de l’avoir appris via un document de la CIA donne aussi une image de l’époque : aujourd’hui, on apprend davantage sur Internet qu’à l’école
    • Il y a eu des réactions négatives, mais ce genre de combinaison d’utilitaires fait justement tout le charme du CLI
    • Que ça vienne de la CIA ou d’ailleurs, si quelqu’un vient d’apprendre xargs, c’est déjà une bonne chose en soi
    • Pour la génération Bell Labs, ça peut sembler vraiment trop basique
  • En 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

    • On m’a aussi recommandé tig, un ancien TUI Git. C’est une bonne source d’inspiration
    • Certains disaient craindre que le code écrit par Claude finisse par casser le dépôt Git
    • Il y avait aussi des gens qui ne savaient pas ce qu’était un TUI
    • Pour un TUI Git, je recommande vivement Magit. C’est aussi très utile pour apprendre
      On peut aussi lire cet article sur la fonctionnalité de rebase de Magit
    • J’ai moi aussi beaucoup de petits outils créés avec Claude. Je me demande si tu les as publiés en open source
  • 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 distant
    Le code est dans mes dotfiles