1366 Stimmen

Wie man lokale Tracking-Branches beschneidet, die nicht mehr auf dem Remote vorhanden sind?

Mit git remote prune origin kann ich die lokalen Zweige entfernen, die nicht mehr auf dem Remote-Server sind.

Aber ich möchte auch die lokalen Zweige entfernen, die von diesen Remote-Zweigen erstellt wurden (eine Überprüfung, ob sie nicht zusammengeführt wurden, wäre schön).

Wie kann ich das machen?

12 Stimmen

8 Stimmen

Einzeiler, plattformübergreifend, sieht nicht aus, als hätte die Katze auf deiner Tastatur geschlafen: npx git-removed-branches (Trockenlauf) oder npx git-removed-branches --prune (für echte Durchführung). Sie müssen bereits node.js installiert haben. Siehe Antworten unten für Details.

0 Stimmen

Normalerweise denke ich, dass diese Dinge absichtlich und nicht automatisch erledigt werden sollten, da man sich sonst öffnet, etwas zu löschen, was man nicht löschen wollte. Also würde ich beim 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-Zweige mit git branch -r erhalten. Die Liste der Zweige mit ihrem Remote-Tracking-Zweig kann mit git branch -vv abgerufen werden. Daher können Sie mit diesen beiden Listen die Remote-Tracking-Zweige 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-Zweige ab und leitet sie durch die Standard-Eingabe an egrep weiter. Und filtert die Zweige heraus, die einen Remote-Tracking-Zweig haben (unter Verwendung von git branch -vv und dem Filtern nach denen, die origin haben) und dann die erste Spalte dieses Ausgabewerts abruft, was der Zweigname sein wird. Schließlich werden alle Zweignamen an den Befehl zum Löschen des Zweiges übergeben.

Da hier die Option -d verwendet wird, werden keine Zweige gelöscht, die nicht in den Branch gemergt wurden, auf dem Sie sind, wenn Sie diesen Befehl ausführen.

26 Stimmen

Das hat bei mir perfekt funktioniert. Irgendwie reicht git fetch -p manchmal nicht aus?

30 Stimmen

Leider funktioniert dies nicht in Git Bash unter Windows. sh.exe": Kann keine Pipe für Prozesssubstitution herstellen: Funktion nicht implementiert sh.exe": egrep -v -f /dev/fd/0: Datei oder Verzeichnis nicht gefunden fatal: Branch-Name erforderlich Irgendwelche Ideen?

2 Stimmen

Das liegt daran, dass /dev/fd/0 für die Standardausgabe unter Windows nicht vorhanden ist. Ich bin mir nicht sicher, was das Äquivalent wäre.

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 eine ordnungsgemäße Löschung 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, meiner Meinung nach! 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 dies versucht, aber es hat nicht funktioniert: git config --global alias.cleaner "branch --merged master | grep -v 'master$' | xargs branch -d"

0 Stimmen

Zweige, die auf 'master' enden, werden nicht gelöscht. Ich benutze git branch --merged master | grep -v '^ master$' | xargs git branch -d nur, weil es dem Format entspricht, wie es im Ausgabeformat des Git-Zweigs ist.

277voto

twalberg Punkte 56757

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

 -p, --prune
        Entferne nach dem Abrufen alle Remote-Tracking-Zweige, die nicht mehr auf dem Remote-Host vorhanden sind.

Vielleicht ist also git fetch -p das, wonach du suchst?

BEARBEITEN: Ok, für diejenigen, die diese Antwort immer noch 3 Jahre später diskutieren, hier sind noch ein paar zusätzliche Informationen, warum ich diese Antwort vorgestellt habe...

Zunächst einmal sagt der Fragesteller, dass er auch "die lokalen Zweige entfernen möchte, die von den Remote-Zweigen erstellt wurden [die nicht mehr auf dem Remote-Host 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 namens A und B. Wenn ich dieses Repository auf mein lokales System klonen, werden meine Kopien lokale Verweise (noch keine tatsächlichen Zweige) namens origin/A und origin/B haben. Nehmen wir nun an, 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 mit einem anderen Namen als seinem Ursprung zu erstellen, und ich habe auch einen lokalen Zweig, der noch nicht auf dem Ursprung-Repository existiert.

Nehmen wir nun an, ich entferne die Zweige A und B im Remote-Repository und aktualisiere mein lokales Repository (git fetch in irgendeiner Form), was dazu führt, dass meine lokalen Verweise origin/A und origin/B verschwinden. Jetzt hat mein lokales Repository immer noch drei Zweige, A, Z und C. Keiner von ihnen hat einen entsprechenden Zweig im Remote-Repository. Zwei von ihnen 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 von B erstellt wurde, weil es im Prozess umbenannt wurde, wahrscheinlich aus gutem Grund. Ohne einen externen Prozess, der Metadaten zur Ursprungs-Zweiginformation aufzeichnet, oder einen Menschen, der die Historie kennt, ist es also unmöglich zu sagen, auf welche der drei Zweige, wenn überhaupt, der Fragesteller abzielt. Ohne externe Informationen, die git nicht automatisch für dich pflegt, ist git fetch -p so nah dran wie möglich, und jede automatische Methode, die wörtlich das zu versuchen, was der Fragesteller gefragt hat, läuft Gefahr, entweder zu viele Zweige zu löschen oder einige zu übersehen, die der Fragesteller sonst löschen möchte.

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

135 Stimmen

Dies löscht nicht die lokalen Zweige, sondern nur die entfernten Zeiger auf die Zweige.

7 Stimmen

Es löscht nur die lokalen Zweige, die nicht im Remote existieren UND auf die Sie noch nie ausgecheckt haben.

18 Stimmen

Du solltest die Frage genauer lesen, wie 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 dies für Sie erledigt (und es sollte plattformübergreifend funktionieren).

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

Dann wird git removed-branches dir alle veralteten lokalen Branches anzeigen, und git removed-branches --prune um sie tatsächlich zu löschen.

Weitere Informationen hier.

7 Stimmen

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

0 Stimmen

Handliche kleine Erweiterung. Installiert und hat einwandfrei unter Windows 10 funktioniert. Kleine Anmerkung: Sie betrachtet nicht zusammengeführte Branches als aufräumbar (Fehler beim Ausführen von --prune, obwohl gedacht -d war aufgerufen) .. sie werden jedoch nicht als solche in der initialen Auflistung angezeigt.

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ückverfolgt wurden. (Stellen Sie sicher, dass Sie auf dem master-Branch sind!)

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 von remote zurückverfolgt wurden.

    mybranch abc1234 [origin/mybranch: gone] Commit-Kommentare
  • -d überprüft, ob er gemerged wurde (-D löscht ihn 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

Nur zur Anmerkung, dass Sie sich vorher auf dem Master befinden sollten, da git branch -d Branches mit HEAD vergleicht.

0 Stimmen

Ausgezeichnet! Ich habe und gesucht nach diesem. Ich wünschte, ich hätte deine Antwort gesehen, bevor ich es selbst herausgefunden habe. 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