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-Server 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

One-Liner, 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 weitere Details.

0 Stimmen

Ich denke normalerweise, dass diese Dinge absichtlich und nicht automatisch erledigt werden sollten, da Sie sich sonst offenlegen, 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 erhalten. Die Liste der Branches mit ihren Remote-Tracking-Branches kann mit git branch -vv abgerufen werden. Verwenden Sie also diese beiden Listen, um die Remote-Tracking-Branches zu finden, die nicht in der Liste der Remotes enthalten sind.

Diese Zeile sollte das Problem lösen (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 erhält die Liste der Remote-Branches und leitet sie an egrep durch die Standardeingabe weiter. Und filtert die Branches heraus, die einen Remote-Tracking-Branch haben (unter Verwendung von git branch -vv und Filtern nach denen, die origin haben), indem die erste Spalte dieser Ausgabe abgerufen wird, was der Branch-Name sein wird. Schließlich werden alle Branch-Namen in den Löschbranch-Befehl übergeben.

Da die Option -d verwendet wird, werden Branches, die nicht in den Branch gemerged wurden, auf dem Sie sich befinden, 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 Prozessersetzung 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 nicht für die Standardausgabe 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 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

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

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 mit dem Namen 'master' am Ende werden nicht gelöscht. Ich verwende git branch --merged master | grep -v '^ master$' | xargs git branch -d nur, weil es so formatiert ist wie in der Git-Zweigausgabe.

277voto

twalberg Punkte 56757

Mitten in den Informationen, die von git help fetch präsentiert werden, gibt es diesen kleinen Punkt:

 -p, --prune
        Entfernt nach dem Holen alle Remote-Tracking-Zweige, die nicht mehr auf dem Remote existieren.

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

BEARBEITEN: Gut, für diejenigen, die 3 Jahre nach der Tatsache immer noch über diese Antwort debattieren, hier noch ein wenig mehr Informationen, warum ich diese Antwort präsentiert habe...

Zunächst sagt der Fragesteller, dass er auch "die lokalen Branches löschen möchte, die von den Remote-Branches erstellt wurden [die nicht mehr auf dem Remote existieren]". Dies ist in git nicht eindeutig möglich. Hier ist ein Beispiel.

Sagen wir, ich habe ein Repo auf einem zentralen Server, und es hat zwei Zweige 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. Nehmen wir 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 einen Branch in meinem lokalen Repo erstellt habe, der einen anderen Namen als sein Ursprung hat, und ich habe auch einen lokalen Branch, der (noch) nicht im Ursprungsrepo existiert.

Angenommen, ich entferne die Branches A und B auf dem Remote-Repo und aktualisiere mein lokales Repo (git fetch in irgendeiner Form), wodurch meine lokalen Verweise origin/A und origin/B verschwinden. Jetzt hat mein lokales Repo immer noch drei Branches, A, Z und C. Keiner davon hat einen entsprechenden Branch im Remote-Repo. Zwei von ihnen wurden "aus ... Remote-Branches erstellt", aber selbst wenn ich weiß, dass es früher 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 ist es wirklich ohne einen externen Prozess zur Aufzeichnung von Branch-Origin-Metadaten oder einen Menschen, der die Historie kennt, unmöglich zu sagen, auf welche der drei Branches der Fragesteller abzielt, wenn überhaupt. Ohne einige externe Informationen, die git nicht automatisch für dich pflegt, ist git fetch -p so nah dran, wie du kommen kannst, und jede automatische Methode, die buchstäblich das macht, was der Fragesteller gefragt hat, läuft Gefahr, entweder zu viele Branches zu löschen oder einige zu verpassen, die der Fragesteller sonst gerne gelöscht hätte.

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

135 Stimmen

Dies löscht nicht die lokalen Branches, sondern nur die Remote-Pointer zu den Branches.

7 Stimmen

Es löscht nur diese lokalen Branches, die nicht im Remote existieren UND auf die Sie 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).

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

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

Mehr Informationen hier.

7 Stimmen

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

0 Stimmen

Handy little Erweiterung. Installiert und funktionierte gut auf Windows 10. Kleiner Hinweis: Es betrachtet nicht zusammengeführte Branches als prunefähig (Fehler beim Ausführen von --prune, dachte nur, dass der Branch -d aufgerufen wurde) .. sie sind jedoch nicht als solche in der ersten angezeigten Liste gekennzeichnet.

19 Stimmen

Das 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 geprüft 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 vom Remote-Branch geprüft wurden.

    mybranch abc1234 [origin/mybranch: gone] Kommentare zum Commit
  • -d überpruft, ob der Branch gemerged wurde (-D löscht ihn unabhängig davon)

    Fehler: Der Branch 'mybranch' wurde 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

Einfach darauf hinweisen, dass Sie sich vorher im Master befinden sollten, weil git branch -d Branches mit HEAD vergleicht.

0 Stimmen

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