1366 Stimmen

Wie kann man lokale Tracking-Zweige beschneiden, die nicht mehr auf dem Remote vorhanden sind?

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

Aber ich möchte auch die lokalen 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 tun?

12 Stimmen

8 Stimmen

Einzeiler, plattformübergreifend, sieht nicht so aus, als hätte die Katze auf deiner 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 in der Regel, dass diese Dinge absichtlich und nicht automatisch erledigt werden sollten, da Sie sich sonst dem Risiko aussetzen, etwas zu löschen, das Sie nicht löschen wollten. Deshalb 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 ihrer Remote-Tracking-Branch kann mit git branch -vv abgerufen werden. So können Sie anhand 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-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 ruft die Liste der Remote-Branches ab und übergibt sie über die Standard-Eingabe an egrep. Er filtert die Branches heraus, die eine Remote-Tracking-Branch haben (unter Verwendung von git branch -vv und Filtern nach denen mit origin), holt dann die erste Spalte dieses Ausgabe, die der Branch-Name sein wird. Schließlich werden alle Branch-Namen an den Branch-Lösch-Befehl übergeben.

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

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 Prozess-Substitution 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 für die Standardausgabe unter Windows nicht existiert. Ich bin mir nicht sicher, was das Äquivalent wäre.

650voto

jackocnr Punkte 16216

Wenn Sie alle lokalen Zweige 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-Zweig verwenden, sollten Sie den Befehl entsprechend ändern:

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

Weitere Informationen.

HINWEIS: Das xargs -d'\n' Parameter wird verwendet, um eine ordnungsgemäße Löschung von Zweigen 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 der Formatierung im git branch Output entspricht.

277voto

twalberg Punkte 56757

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

 -p, --prune
        Entfernen Sie nach dem Abrufen alle Remote-Tracking-Branches, die auf dem Remote nicht mehr existieren.

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

EDIT: Also, für diejenigen, die 3 Jahre nach der Tatsache immer noch über diese Antwort diskutieren, hier sind noch ein paar weitere Informationen, warum ich diese Antwort präsentiert habe...

Zunächst sagt der OP, dass er auch "die lokalen Branches entfernen möchte, die aus jenen Remote-Branches erstellt wurden, die nicht mehr auf dem Remote sind". 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 namens A und B. Wenn ich dieses Repo auf mein lokales System klonen, wird mein Klon lokale Verweise (noch keine tatsächlichen Branches) namens origin/A und origin/B haben. 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 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.

Angenommen, ich entferne beide Branches A und B im Remote-Repo und aktualisiere mein lokales Repo (git fetch in irgendeiner Form), was dazu führt, dass meine lokalen Verweise 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 von ihnen wurden "aus ... Remote-Branches erstellt", aber selbst wenn ich weiß, dass es einmal einen Branch 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, ohne einen externen Prozess, der Metadaten zum Ursprungszweig aufzeichnet, oder einen Menschen, der die Historie kennt, ist es unmöglich zu sagen, auf welche der drei Branches, wenn überhaupt, der OP abzielt. Ohne einige externe Informationen, die git nicht automatisch für Sie pflegt, ist git fetch -p so ziemlich das, was Sie bekommen können, und jede automatische Methode, die wörtlich versucht, was der OP gefragt hat, birgt das Risiko, entweder zu viele Branches zu löschen oder einige zu verpassen, die der OP sonst löschen würde.

Es gibt auch andere Szenarien, z.B. 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 aus 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, sie zuzuordnen...

135 Stimmen

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

7 Stimmen

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

18 Stimmen

Du solltest die Frage genauer lesen, wie Jaap feststellt. Leute, 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).

Installieren Sie es mit: npm install -g git-removed-branches

Und dann wird git removed-branches Ihnen 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 Sie das Leben leichter machen, unabhängig von der Plattform.

0 Stimmen

Handy kleine Erweiterung. Installiert und funktioniert problemlos unter Windows 10. Kleiner Hinweis: Sie betrachtet nicht zusammengeführte branches als prune-able (Fehler beim Ausführen von --prune, war nur der Gedanke, dass branch -d aufgerufen wurde).. sie sind jedoch nicht als solche in der initialen Auflistung angegeben.

19 Stimmen

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

181voto

wisbucky Punkte 26902

Das löscht die lokalen Branches, für die die Remote-Tracking-Branches beschnitten wurden. (Stellen Sie sicher, dass Sie sich im 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 von remote beschnitten 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 darauf hinweisen, dass Sie sich vorher auf dem Master befinden sollten, da git branch -d Branches mit HEAD vergleicht.

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