- In internen CIA-Entwicklungsdokumenten wurde ein einfacher Befehl entdeckt, der das alte Problem des Aufräumens von Git-Branches löst
git branch --merged | grep -v "\*\|master" | xargs -n 1 git branch -d - Der Befehl löscht aus der Ausgabe von
git branch --mergedalle gemergten Branches gesammelt, außer dem aktuellen Branch und master - Es gibt auch eine für moderne Projekte angepasste Version, die
mainunddevelopausnimmt - Der Befehl kann als Git-Alias registriert werden, um wiederkehrende Aufgaben zu automatisieren, und ist trotz seiner Einfachheit ein nützliches Werkzeug für dauerhafte Effizienzgewinne und ein aufgeräumtes Repository
Ein in Vault7 entdeckter Git-Tipp
- Die 2017 von WikiLeaks veröffentlichten Vault7-Dokumente enthielten die Hacking-Tools der CIA und interne Entwicklungsdokumente
- Auf einer dieser Seiten fand sich eine Sammlung von Git-Tipps und -Tricks, darunter meist übliche Hinweise zu Commit-Korrekturen, Stash und der Verwendung von
bisect
- Auf einer dieser Seiten fand sich eine Sammlung von Git-Tipps und -Tricks, darunter meist übliche Hinweise zu Commit-Korrekturen, Stash und der Verwendung von
- Ein dort gefundener Einzeiler ist bis heute in meiner
~/.zshrcerhalten geblieben
Das Problem mit alten Branches
- In lokalen Git-Repositories sammeln sich mit der Zeit gemergte Branches an, was das Aufräumen erschwert
- Feature-Branches, Hotfixes und experimentelle Branches bleiben nach dem Merge bestehen, sodass die Ausgabe von
git branchunübersichtlich wird
- Feature-Branches, Hotfixes und experimentelle Branches bleiben nach dem Merge bestehen, sodass die Ausgabe von
- Mit
git branch --mergedlassen sich gemergte Branches anzeigen, aber das manuelle Löschen ist umständlich
Der ursprüngliche Befehl aus dem CIA-Dokument
- Der ursprünglich vorgeschlagene Befehl lautet
git branch --merged | grep -v "\*\|master" | xargs -n 1 git branch -d - Erläuterung der Bestandteile
git branch --merged: Gibt eine Liste aller lokalen Branches aus, die in den aktuellen Branch gemergt wurdengrep -v "\*\|master": Schließt den aktuellen Branch (*) undmasterausxargs -n 1 git branch -d: Löscht die übrigen Branches sicher einzeln (-dlöscht keine nicht gemergten Branches)
Modernisierte Version des Befehls
- Da die meisten Projekte den Branch
mainverwenden, kann der Befehl wie folgt angepasst werdengit branch --merged origin/main | grep -vE "^\s*(\*|main|develop)" | xargs -n 1 git branch -d - Wenn man ihn nach dem Deployment auf dem Branch
mainausführt, reduziert sich eine lange Liste von Branches auf nur noch wenige - Der Befehl kann als Git-Alias registriert werden, um ihn bequem auszuführen
alias ciaclean='git branch --merged origin/main | grep -vE "^\s*(\*|main|develop)" | xargs -n 1 git branch -d'- Danach genügt im Repository der Befehl
ciaclean, um das Aufräumen automatisch auszuführen
- Danach genügt im Repository der Befehl
Effizienz und Praxistauglichkeit
- Dieser Befehl spart jede Woche ein paar Minuten und hilft dabei, die Branch-Liste sauber zu halten
- Er gilt als einfaches, aber praktisches Werkzeug, das kontinuierliche Produktivitätsgewinne bringt
4 Kommentare
In den HN-Kommentaren gibt es offenbar jemanden, der ein Programm verwendet, das ich erstellt habe.
Ich verwende auch einen Alias namens
git gone. Sehr praktisch. -alias.gone = ! git fetch -p && git for-each-ref --format '%(refname:short) %(upstream:track)' | awk '$2 == "[gone]" {print $1}' | xargs -r git branch -DIch verwende zum Aufräumen zwar kein reines Git, sondern das Tool
gh-poi.https://github.com/seachicken/gh-poi
Hacker-News-Kommentare
Ich verwende einen Alias namens
git tidy, um Branches aufzuräumenDie Standard-Branches (
main,master) werden nicht gelöscht, und weder der aktuelle Branch noch Branches in anderen worktrees werden angetastetBranches, die auf dem Remote verschwunden sind, werden ebenfalls automatisch gelöscht, und der Code steht in meinen dotfiles
init.defaultBranchzu verwenden ist riskant. Der Name des Standard-Branches kann je nach Repository unterschiedlich sein, und diese Einstellung ist global, also muss sie vorab festgelegt werdenIch habe deshalb einen Alias namens
git defaultgebaut, der den tatsächlichen Standard-Branch automatisch vom Remote (origin) ermitteltIch nutze einen Cleanup-Befehl, der in
fzfintegriert istDamit kann ich gemergte Branches vorab auswählen und gesammelt löschen, auf Wunsch aber auch einzelne ausschließen
Remote-Branches werden ebenfalls mit aufgeräumt, und der Code steht in meiner .gitconfig
Außerdem verwende ich die Variable
user.primaryBranch, um je Repository unterschiedliche Standard-Branches festzulegeninit.defaultBranchverwenden. Selbst bei bereits initialisierten Repositories funktioniert es, wenn mangit config --local init.defaultBranch mainsetztgit pull origin main:mainund danachgit rebase maingit branch --mergedfunktioniert in Repositories, die squash merge verwenden, nicht zuverlässigDer Grund ist, dass die SHA des gesquashten Commits sich vom HEAD des ursprünglichen Branches unterscheidet
Mich würde interessieren, ob es ein Tool gibt, das gesquashte Branches sicher erkennen kann
Das ist nicht perfekt, aber praktisch genug, und vor dem Löschen erscheint immer eine Bestätigungsabfrage
Ich habe mich dabei an der Einstellung zur automatischen Branch-Löschung von GitHub orientiert
Die meisten hängen dafür einen Hook an das Löschen des Remote-Branches
Dafür verwende ich einen Alias namens
git gone, der nachgit fetch -pBranches im Status[gone]aufräumtDeshalb nutze ich ein Skript, das
git branch --merged,git cherryundgit log grepkombiniertAllerdings kann es Fehlalarme geben, wenn Commits per amend geändert wurden oder mehrere Commits beteiligt sind
Ich räume gemergte Branches mit einem Alias namens
git lintaufmain,masterundstablewerden dabei ausgelassen, und ich verwende oft die Kombinationgit pull --prune && git lintDer Git-Befehl selbst ist unspektakulär, aber ich fand es interessant, beim Herumklicken auf ein Dokument aus einer Wikileaks-Quelle zu stoßen
Das „Fine Dining“-Projekt der CIA war ein Tool, das auf USB-Sticks versteckte Malware als App tarnte
Das ursprüngliche Problem ließe sich eigentlich schon dadurch lösen, dass man einfach nur eine Liste nicht gemergter Branches ausgibt
Es ist seltsam, dass so ein natürlicher Arbeitsablauf mehrere Zeilen Bash braucht
Angesichts der Größe der Git-Codebasis ist es schade, dass es dafür keine eingebaute Funktion gibt
Siehe auch diesen Blogbeitrag
xargsoder eine for-Schleife ein bisschen beherrscht, ist das eine KleinigkeitAls eingebauter Befehl müsste es viele Sonderfälle behandeln und würde dadurch eher komplizierter werden
Am Ende gab es auch Reaktionen wie: „Klingt, als hätte da jemand gerade erst
xargsgelernt“Ich selbst habe solche Dinge früher auch aus Blogs und Artikeln gelernt
xargsgelernt hat, ist das an sich schon etwas CoolesIch bin derzeit regelrecht TUI-süchtig. Wenn mich etwas stört, bitte ich Claude Code einfach, mir dafür eine TUI zu bauen
Mit der Textual-Bibliothek habe ich eine TUI zur Verwaltung von Git-Worktrees gebaut, und Claude kommt mit Python-Code ziemlich gut zurecht
tig, eine ältere Git-TUI. Auch zur Inspiration ist das gutAuch dieser Artikel über die Rebase-Funktion von Magit ist lesenswert
Ich habe etwas Ähnliches auch in der Fish-Shell umgesetzt
Es ist eine Funktion, mit der man per
fzfBranches auswählen und löschen kann, die auf dem Remote verschwunden sindDer Code steht in meinen dotfiles