1366 Stimmen

Wie man lokale Tracking-Zweige beschneidet, die nicht mehr auf 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 Prü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 echt). Sie müssen bereits node.js installiert haben. Siehe Antworten unten für Details.

0 Stimmen

Ich denke normalerweise, dass diese Dinge absichtlich und nicht automatisch durchgeführt werden sollten, da Sie sich sonst dazu bringen, etwas zu löschen, das Sie nicht löschen wollten. Daher 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 ihren Remote-Tracking-Branches 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 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 die Standardeingabe weiter. Es filtert die Branches, die einen Remote-Tracking-Branch haben (unter Verwendung von git branch -vv und Filtern nach denen, die origin haben), dann wird die erste Spalte dieses Outputs abgerufen, was der Branch-Name sein wird. Schließlich werden alle Branch-Namen dem Branch-Löschbefehl übergeben.

Da die Option -d verwendet wird, werden Branches, die nicht in den Branch übergeführt wurden, von dem aus Sie diesen Befehl ausführen, nicht gelöscht.

26 Stimmen

Das hat für mich perfekt funktioniert. Irgendwie reicht git fetch -p nicht immer aus?

30 Stimmen

Leider funktioniert das 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

Dies liegt daran, dass /dev/fd/0 in Windows nicht existiert, daher bin ich 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 Parameter xargs -d'\n' 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, würde ich sagen! 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 verwende git branch --merged master | grep -v '^ master$' | xargs git branch -d nur, weil es dem Format entspricht, wie es im git branch Output 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
        Nach dem Abrufen entfernen Sie alle Remote-Tracking-Branches, die nicht mehr auf dem Remote existieren.

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

EDIT: Okay, für diejenigen, die auch 3 Jahre später noch über diese Antwort diskutieren, hier sind einige zusätzliche Informationen, warum ich diese Antwort präsentiert habe...

Zunächst sagt der OP, dass er auch "die lokalen Branches entfernen will, die von diesen 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 Clone 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 im Ursprungs-Repo existiert.

Nehmen wir 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 Verweise origin/A und origin/B verschwinden. Jetzt 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 "von ... 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 von B erstellt wurde, weil es im Prozess umbenannt wurde, wahrscheinlich aus gutem Grund. Also, ohne externen Prozess, der Branch-Ursprungs-Metadaten aufzeichnet, oder einen Menschen, der die Historie kennt, ist es unmöglich zu sagen, auf welche der drei Branches der OP abzielt. Ohne externe Informationen, die git nicht automatisch für Sie erstellt, ist git fetch -p so nah wie möglich an dem, was Sie erreichen können, und jeder automatische Versuch, wörtlich das zu tun, was der OP gefragt hat, birgt das Risiko, entweder zu viele Branches 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 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 eine wörtliche Interpretation der Frage des OPs würde erfordern, alle drei zu entfernen. Das mag jedoch nicht wünschenswert sein, selbst wenn man einen zuverlässigen Weg finden könnte, sie zuzuordnen...

135 Stimmen

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

7 Stimmen

Es löscht nur diese lokalen Branches, die nicht im Remote existieren UND auf die du nie eingecheckt hast.

18 Stimmen

Du solltest die Frage genauer lesen, wie Jaap bemerkt. Personen, die für diese Antwort stimmen, sollten auch genau 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 zeigt Ihnen git removed-branches alle veralteten lokalen Branches und git removed-branches --prune zum tatsächlichen Löschen.

Hier finden Sie weitere Informationen.

7 Stimmen

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

0 Stimmen

Handliche kleine Erweiterung. Installiert und funktionierte gut unter Windows 10. Kleine Anmerkung: Es betrachtet nicht verschmolzene Zweige als lösbar (Fehler beim Ausführen von --prune, gerade gedacht Zweig -d wurde aufgerufen) .. sie sind 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 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 gelöscht 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 noch nicht vollständig gemerged.

20 Stimmen

Du kannst den Befehl noch kürzer machen mit git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d

11 Stimmen

Es wird nur darauf hingewiesen, dass Sie sich vor dem Ausführen darauf befinden sollten git branch -d auf dem Master, denn es vergleicht Branches gegen HEAD.

0 Stimmen

Ausgezeichnet! Ich habe danach gesucht. 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