1366 Stimmen

Wie werden lokale Tracking-Branches beschnitten, die nicht mehr auf dem Remote existieren?

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

Aber ich möchte auch die lokalen Branches entfernen, die von diesen Remote-Branches erstellt wurden (eine Überprüfung, ob sie ungemerged sind, wäre schön).

Wie kann ich das tun?

12 Stimmen

8 Stimmen

Eine Zeile, plattformübergreifend, sieht nicht aus, als ob die Katze auf deiner Tastatur geschlafen hätte: npx git-removed-branches (trocken laufen) 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 solche Dinge bewusst und nicht automatisch gemacht werden sollten, da man sich sonst versehentlich etwas löschen könnte, das man nicht löschen wollte. 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 erhalten. Die Liste der Branches mit ihrem Remote-Tracking-Branch kann mit git branch -vv abgerufen werden. Mit diesen beiden Listen können Sie die Remote-Tracking-Branches finden, die nicht in der Liste der Remotes enthalten sind.

Diese Zeile sollte den Trick machen (erfordert bash oder zsh, funktioniert nicht mit der Standard-Borne-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 erhält die Liste der Remote-Branches und leitet sie an egrep über die Standardeingabe weiter. Und filtert die Branches heraus, die einen Remote-Tracking-Branch haben (unter Verwendung von git branch -vv und Filterung nach denen, die origin haben), dann die erste Spalte dieser Ausgabe bekommt, die der Branch-Name sein wird. Schließlich werden alle Branch-Namen in den Branch-Löschbefehl übergeben.

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

26 Stimmen

Das hat bei mir perfekt 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 Prozesssubstitution erstellen: 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 in Windows für die Standardausgabe nicht existiert. 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 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 mir 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 verwende git branch --merged master | grep -v '^ master$' | xargs git branch -d, nur weil es dem Format entspricht, wie es in der Git-Branch-Ausgabe angezeigt wird.

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-Branches, die nicht mehr auf dem Remote vorhanden sind.

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

BEARBEITEN: OK, für diejenigen, die diese Antwort 3 Jahre nach dem Fakt noch diskutieren, hier ein wenig mehr Informationen, warum ich diese Antwort vorgestellt habe...

Zunächst sagt der OP, dass sie auch "diese lokalen Branches entfernen möchten, die von diesen Remote-Branches [die nicht mehr auf dem Remote vorhanden sind] erstellt wurden". Dies ist in git nicht eindeutig möglich. Hier ist ein Beispiel.

Angenommen, ich habe ein Repo auf einem zentralen Server und es hat zwei Branches, genannt A und B. Wenn ich dieses Repo auf mein lokales System klonen, wird mein Klon lokale Verzweigungen (noch keine tatsächlichen Branches) namens origin/A und origin/B haben. Nun lasst uns annehmen, dass ich folgendes tue:

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 Branch in meinem lokalen Repo mit einem anderen Namen als seinem Ursprung zu erstellen, und ich habe auch einen lokalen Branch, der (noch) nicht auf dem Ursprungs-Repo existiert.

Nehmen wir nun an, ich entferne sowohl die Branches A als auch B im Remote-Repo und aktualisiere mein lokales Repo (git fetch in irgendeiner Form), was dazu führt, dass meine lokalen Verzweigungen origin/A und origin/B verschwinden. Nun hat mein lokales Repo immer noch drei Branches, A, Z und C. Keiner von ihnen hat einen entsprechenden Branch im Remote-Repo. Zwei davon wurden "aus ... Remote-Branches erstellt", aber selbst wenn ich weiß, dass es einen Branch namens B im Ursprungsrepo 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, ohne irgendeinen externen Prozess, der Metadaten des Branch-Ursprungs aufzeichnet, oder einen Menschen, der die Geschichte kennt, ist es unmöglich zu sagen, auf welche der drei Branches, wenn überhaupt, der OP abzielt, um sie zu entfernen. Ohne irgendwelche externen Informationen, die git nicht automatisch für Sie pflegt, kommt git fetch -p dem schon ziemlich nahe, und eine automatische Methode, die wörtlich das versucht, was der OP gefragt hat, läuft Gefahr, entweder zu viele Branches zu löschen oder einige zu verpassen, die der OP sonst gelöscht haben möchte.

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

135 Stimmen

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

7 Stimmen

Es löscht nur diese lokalen Branches, die nicht auf dem Remote existieren UND auf die du noch nie ausgecheckt hast.

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

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

Weitere Informationen hier.

7 Stimmen

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

0 Stimmen

Kleine praktische Erweiterung. Installiert und hat auf Windows 10 einwandfrei funktioniert. Kleine Anmerkung: Es betrachtet nicht zusammengeführte Branches als bereinigbar (Fehler beim Ausführen von --prune, dachte nur, dass branch -d aufgerufen wird) .. sie werden jedoch nicht als solche in der anfänglichen 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ückgeschnitten wurden. (Stellen Sie sicher, dass Sie sich auf dem master Branch 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 der Branch 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 Kenntnis, dass Sie sich vorher auf Master befinden sollten, da git branch -d die Branches mit HEAD vergleicht.

0 Stimmen

Ausgezeichnet! Ich habe danach gesucht. Ich wünschte, ich hätte Ihre 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