1366 Stimmen

Wie kann man lokale Tracking-Branches beschneiden, die nicht mehr auf dem Remote existieren?

Mit git remote prune origin kann ich die lokalen Branches entfernen, die nicht mehr auf dem Remote vorhanden sind.

Aber ich möchte auch lokale Branches entfernen, die von diesen Remote-Branches erstellt wurden (eine Überprüfung, ob sie nicht zusammengeführt wurden, wäre nett).

Wie kann ich das machen?

12 Stimmen

8 Stimmen

Einzeiler, plattformübergreifend, sieht nicht aus, als hätte die Katze auf Ihrer Tastatur geschlafen: npx git-removed-branches (Trockenlauf) oder npx git-removed-branches --prune (für echt). Du musst bereits Node.js installiert haben. Siehe Antworten unten für Details.

0 Stimmen

Ich denke normalerweise, dass diese Dinge absichtlich und nicht automatisch gemacht werden sollten, da Sie sich ansonsten selbst dem Risiko aussetzen, etwas zu löschen, das Sie nicht löschen wollten. Also würde ich bei git branch -d localBranchName und git push origin --delete remoteBranchName bleiben.

1473voto

Schleis Punkte 38294

Nach dem Beschneiden können Sie die Liste der Remote-Branches mit git branch -r abrufen. Die Liste der Branches mit ihrem Remote-Tracking-Branch kann mit git branch -vv abgerufen werden. So können Sie mithilfe dieser beiden Listen die Remote-Tracking-Branches finden, die nicht in der Liste der Remotes enthalten sind.

Diese Zeile sollte den Trick tun (erfordert bash oder zsh, funktioniert nicht mit der Standard-Bourne-Shell):

git fetch -p ; git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d

Dieser String ruft die Liste der Remote-Branches ab und leitet sie an egrep über den Standard-Input weiter. Er filtert die Branches heraus, die einen Remote-Tracking-Branch haben (unter Verwendung von git branch -vv und Filtern nach denen, die origin haben), dann die erste Spalte dieses Ausgabes holen, die der Branch-Name sein wird. Schließlich werden alle Branch-Namen an den Lösch-Befehl für Branches weitergeleitet.

Da hier die Option -d verwendet wird, werden Branches nicht gelöscht, die nicht in den Zweig verschmolzen wurden, auf dem Sie sich befinden, wenn Sie diesen Befehl ausführen.

26 Stimmen

Das hat bei mir einwandfrei funktioniert. Irgendwie reicht git fetch -p nicht immer aus?

30 Stimmen

Leider funktioniert dies nicht in Git Bash unter Windows. sh.exe": kann keine Pipe für Prozess-Substitution erstellen: Funktion nicht implementiert sh.exe": egrep -v -f /dev/fd/0: Keine solche Datei oder Verzeichnis fatal: Branch-Name erforderlich Irgendwelche Ideen?

2 Stimmen

Dies liegt daran, dass /dev/fd/0 für die Standardausgabe in Windows nicht existiert. Ich bin mir nicht sicher, was dementsprechend verwendet werden könnte.

650voto

jackocnr Punkte 16216

Wenn Sie alle lokalen Branches löschen möchten, die bereits in den Master zusammengeführt wurden, können Sie den folgenden Befehl verwenden:

git branch --merged master | grep -v '^[ *]*master$' | xargs -d'\n' git branch -d

Wenn Sie main als Ihren Master-Branch verwenden, sollten Sie den Befehl entsprechend anpassen:

git branch --merged main | grep -v '^[ *]*main$' | xargs -d'\n' git branch -d

Weitere Informationen.

HINWEIS: Der xargs -d'\n' Parameter wird verwendet, um das ordnungsgemäße Löschen von Branches mit einem Apostroph im Namen zu ermöglichen, siehe https://unix.stackexchange.com/questions/38148/why-does-xargs-strip-quotes-from-input.

6 Stimmen

Hat perfekt funktioniert, denke ich! Könnte jemand erklären, ob diese Antwort etwas anders macht als die akzeptierte Antwort?

0 Stimmen

Ist es möglich, dies in ein globales Git-Alias umzuwandeln? Ich habe es versucht, aber es hat nicht funktioniert: git config --global alias.cleaner "branch --merged master | grep -v 'master$' | xargs branch -d"

0 Stimmen

Zweige, die mit 'master' enden, werden nicht gelöscht. Ich benutze git branch --merged master | grep -v '^ master$' | xargs git branch -d nur, weil es zum Format der git-Zweigausgabe passt.

277voto

twalberg Punkte 56757

Mitten in den Informationen, die von git help fetch präsentiert werden, gibt es dieses kleine Element:

 -p, --prune
        Nach dem Abrufen, entfernen Sie alle Remote-Tracking-Zweige, die nicht mehr auf dem Remote vorhanden sind.

Also vielleicht ist git fetch -p das, wonach Sie suchen?

BEARBEITEN: Ok, für diejenigen, die diese Antwort immer noch 3 Jahre nach dem Fakt debattieren, hier sind ein paar weitere Informationen, warum ich diese Antwort präsentiert habe...

Zuerst sagt der OP, dass sie "auch die lokalen Zweige entfernen wollen, die von diesen Remote-Zweigen erstellt wurden [die nicht mehr auf dem Remote vorhanden sind]". Dies ist in git nicht eindeutig möglich. Hier ist ein Beispiel.

Angenommen, ich habe ein Repository auf einem zentralen Server und es hat zwei Zweige, die A und B genannt werden. Wenn ich dieses Repository auf mein lokales System klonen, wird mein Klon lokale Verweise haben (noch keine tatsächlichen Zweige) namens origin/A und origin/B. Angenommen, ich mache folgendes:

git checkout -b A origin/A
git checkout -b Z origin/B
git checkout -b C 

Die relevanten Fakten hier sind, dass ich aus irgendeinem Grund beschlossen habe, einen Zweig in meinem lokalen Repository zu erstellen, der einen anderen Namen als das Ursprungs hat, und dass ich auch eine lokale Zweig habe, die (noch) nicht im Ursprungs-Repository existiert.

Angenommen, ich entferne sowohl die Zweige A als auch B im Remote-Repository und aktualisiere mein lokales Repository (git fetch irgendeiner Form), was dazu führt, dass meine lokalen Verweise origin/A und origin/B verschwinden. Jetzt habe mein lokales Repository drei Zweige, A, Z und C. Keiner von ihnen hat einen entsprechenden Zweig im Remote-Repository. Zwei davon wurden „aus ... Remote-Zweigen erstellt“, aber selbst wenn ich weiß, dass es einen Zweig namens B im Ursprung gab, habe ich keine Möglichkeit zu wissen, dass Z aus B erstellt wurde, weil es im Prozess umbenannt wurde, wahrscheinlich aus gutem Grund. Also, wirklich, ohne irgendetwas externes, das Branch-Origin-Metadaten aufzeichnet, oder einen Menschen, der die Geschichte kennt, ist es unmöglich zu sagen, auf welchen der drei Zweige der OP abzielt, und ob überhaupt. Ohne einige externe Informationen, die git nicht automatisch für Sie pflegt, kommt git fetch -p so nah wie möglich ran, und jede automatische Methode, die buchstäblich versucht, was der OP gefragt hat, es birgt das Risiko, entweder zu viele Zweige zu löschen oder einige zu übersehen, die der OP sonst löschen möchte.

Es gibt auch andere Szenarien, zum Beispiel, wenn ich drei separate Zweige von origin/A erstelle, um drei verschiedene Ansätze für etwas zu testen, und dann origin/A verschwindet. Jetzt habe ich drei Zweige, die offensichtlich nicht namensgleich sein können, aber sie wurden von origin/A erstellt, und daher würde eine wörtliche Interpretation der Frage des OPs erfordern, alle drei zu entfernen. Das mag jedoch nicht wünschenswert sein, wenn man überhaupt einen zuverlässigen Weg finden könnte, um sie abzugleichen...

135 Stimmen

Das löscht nicht die lokalen Branches, sondern nur die Remote-Zeiger auf die Branches.

7 Stimmen

Es löscht nur diese lokalen Branches, die nicht existieren in Remote UND du hast nie einen Checkout auf ihnen gemacht.

18 Stimmen

Du solltest die Frage genauer lesen, wie auch Jaap bemerkt. Personen, die für diese Antwort stimmen, sollten auch lesen, worum es in der Frage wirklich geht.

226voto

tzachs Punkte 3465

Es gibt ein tolles npm-Paket, das das für Sie erledigt (und es sollte plattformübergreifend funktionieren).

Installiere es mit: npm install -g git-removed-branches

Und dann zeigt Ihnen git removed-branches alle veralteten lokalen Branches an, und git removed-branches --prune um sie tatsächlich zu löschen.

Mehr Infos hier.

7 Stimmen

Dies sollte wirklich mehr Upvotes haben. Vielen Dank, dass Sie das Leben einfacher machen, unabhängig von der Plattform.

0 Stimmen

Handliche kleine Erweiterung. Installiert und hat auf Windows 10 gut funktioniert. Kleiner Hinweis: Es betrachtet nicht zusammengeführte Branches als bereinigbar (Fehler beim Ausführen von --prune, dachte nur, dass branch -d aufgerufen wurde) ... sie sind jedoch nicht als solche in der ursprünglichen Liste angegeben.

19 Stimmen

Dies ist meine Lieblingsantwort. npx git-removed-branches funktioniert wie ein Traum.

181voto

wisbucky Punkte 26902

Dies löscht die lokalen Branches, für die die Remote-Tracking-Branches zurückgeschnitten wurden. (Stellen Sie sicher, dass Sie sich im master-Zweig befinden!)

git checkout master
git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -d

Details:

  • git branch -vv zeigt "gone" für lokale Branches an, die vom Remote zurückgeschnitten wurden.

    mybranch abc1234 [origin/mybranch: gone] Commit-Kommentare
  • -d überprüft, ob es gemerged wurde (-D löscht es unabhängig davon)

    Fehler: Der Branch 'mybranch' ist nicht vollständig gemerged.

20 Stimmen

Sie können den Befehl sogar verkürzen mit git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d

11 Stimmen

Ich weise nur darauf hin, dass du auf Master sein solltest, bevor du dies machst, denn git branch -d vergleicht Branches mit HEAD.

0 Stimmen

Ausgezeichnet! Ich habe danach gesucht. Ich wünschte, ich hätte deine Antwort gesehen, bevor ich selbst darauf gekommen bin. Es hätte mir ein paar Minuten gespart. Hier ist meine andere Antwort: stackoverflow.com/questions/15661853/…

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X