Löschen Sie lokale Git-Zweige, nachdem Sie sie auf dem Remote-Repo gelöscht haben


162

Ich möchte, dass meine lokalen und Remote-Repositorys in Bezug auf Zweige immer synchron sind.

Nach einer Pull Request-Überprüfung auf GitHub füge ich meinen Zweig dort zusammen und entferne ihn (remote). Wie kann ich diese Informationen in meinem lokalen Repository abrufen und Git veranlassen, auch meine lokale Version des Zweigs zu entfernen?


Möchten Sie Ihre Remote-Tracking-Zweige, lokalen Zweige oder beides löschen? Sie können tatsächlich einen Alias ​​(Bash oder Git) schreiben, der alle gelöschten Remote-Zweige übernimmt und lokale Kopien zum Löschen findet, alles in einem Befehl.

Versuchen Sie vielleicht, die folgenden Befehle zu verwenden, um etwas zu finden, git ls-remoteund git show-ref.

Vielleicht möchten Sie auch auschecken git symbolic-refund git update-ref.

Vielen Dank für Ihre Hilfe. Ich habe die Antwort woanders gefunden. Siehe meine Antwort.
SF89

Antworten:


180

Der schnelle Weg

git branch --merged | grep -v "\*" | xargs -n 1 git branch -d

NB: Wenn Sie nicht eingeschaltet sind master, kann dies den Zweig löschen. Lesen Sie weiter für den "besseren Weg".

Stellen Sie sicher, dass wir den Meister behalten

Sie können sicherstellen, dass masteroder ein anderer Zweig in dieser Angelegenheit nicht entfernt wird, indem grepSie nach mehr suchen. In diesem Fall würden Sie gehen:

git branch --merged | grep -v "\*" | grep -v "YOUR_BRANCH_TO_KEEP" | xargs -n 1 git branch -d

Also , wenn wir wollten , halten master, developund stagingzum Beispiel, würden wir gehen:

git branch --merged | grep -v "\*" | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d

Machen Sie dies zu einem Alias

Da es etwas lang ist, möchten Sie möglicherweise einen Alias ​​zu Ihrem .zshrcoder hinzufügen .bashrc. Meins heißt gbpurge(für git branches purge):

alias gbpurge='git branch --merged | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d'

Laden Sie dann Ihr .bashrcoder neu .zshrc:

. ~/.bashrc

oder

. ~/.zshrc

Sie können die Befehle in einen Alias ​​einfügen und daraus einen einzelnen Befehl machen. Da es sich jedoch branchum ein Porzellan und nicht um einen Installationsbefehl handelt , sollten Sie in zukünftigen Versionen von Git auf Änderungen an der Benutzeroberfläche achten, die diese möglicherweise beschädigen.

1
Perfekt! Beachten Sie, dass nach dem Github-Workflow der lokale Zweig mastergelöscht wird.
Rubens Mariuzzo

Nein, ich bin mir ziemlich sicher, dass es dort bleibt (ich benutze es jeden Tag und es scheint das nicht zu tun).
sf89

4
Zu Ihrer Information, wenn Sie mehrere Zweige behalten möchten, können Sie einen einzigen Grep verwenden, wie grep -Ev '(\*|master|important-branch)'
Andrew Burns

4
Wenn Sie dies ~/.gitconfigstattdessen in Ihr hinzufügen möchten , fügen Sie dem [alias]Abschnitt Folgendes hinzu : gbpurge = !"git branch --merged | grep -Ev '\\*|master|develop|staging' | xargs -n 1 git branch -d"(keine Notwendigkeit, () im grep-Ausdruck zu verwenden).
dskrvk

82

Ich verwende den gleichen Ablauf mit GitHub und fand die vorherigen Antworten nicht zufriedenstellend, da git branch --mergedListenzweige aufgelistet wurden, die zusammengeführt wurden, aber in meinem Fall wurden nicht alle entfernt entfernt. Das hat bei mir funktioniert:

git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d

wo:

  • git fetch --all -p: Aktualisieren Sie den Status der lokalen Niederlassungen
  • git branch -vv: Listet den Status der lokalen Niederlassungen auf
  • grep ": gone]": gelöschte filtern
  • awk '{ print $1 }': extrahieren ihre Namen
  • xargs -n 1 git branch -d: Übergeben Sie den Namen an den Befehl delete

Hinweis: Wenn Sie möchten, können Sie -D anstelle von -d verwenden, wodurch das Löschen erzwungen wird.

Beispielsweise:

someUsr@someHost:~/repo$ git branch -a
basic-testing
integration-for-tests
* master
origin
playground-for-tests
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services

someUsr@someHost:~/repo$ git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d
Fetching origin
Deleted branch integration-for-tests (was fbc609a).
Deleted branch playground-for-tests (was 584b900).

someUsr@someHost:~/repo$ git branch -a
basic-testing
* master
origin
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services

Referenz:

http://git-scm.com/book/en/v2/Git-Branching-Remote-Branches


3
Ich habe mir git checkout master; git pull origin master; git fetch --all -p; git branch -vv | grep gone | awk '{ print $1 }' | xargs -n 1 git branch -d
erlaubt

Beachten Sie, dass branch -vvdie letzte Festschreibungsnachricht aus dem Zweig angezeigt wird. Wenn Sie in dieser Nachricht zufällig "gegangen" grep gonewären, würde dies auch diesen Zweig treffen. Ist grep ": gone]"also wohl etwas sicherer zu bedienen.
Chawkinsuf

1
Dies ist die eigentliche Antwort auf die Frage. Danke dir.
Andrei Gladkyi

1
Noch besser:awk '$3 $4 ~ /:gone]$/ { print $1 }'
Jakub Bochenski

3
Abgesehen davon ist -Dstattdessen -ddie perfekte Antwort!
Cas

72

Versuchen:

Git Pull - beschneiden

Dadurch wird Ihr lokaler Zweig gelöscht, wenn der entsprechende Remote-Zweig gelöscht wird.

Aktualisiert:

Die obige Aussage ist nicht so richtig.

In der Tat läuft git pull --prunewird die Remote-Tracking - Zweige nur ENTFERNT so wie

Fernbedienungen / Herkunft / fff
Fernbedienungen / Herkunft / Dev
Fernbedienungen / Herkunft / Master

Anschließend können Sie die git branch -rauf Ihrem Computer verbleibenden Zweigstellen für die Fernverfolgung überprüfen. Angenommen, die linken Zweige sind:

Herkunft / Entwicklung
Herkunft / Meister

was bedeutet, die Niederlassung origin/fff gelöscht wird.

Also, nach dem Laufen git pull --pruneeinfach laufen:

git branch --merged | grep -vFf <(git branch -r | cut -d'/' -f2-)

Sie können alle lokalen Niederlassungen herausfinden, die:

  1. keine korrespondierenden entfernten Zweige mehr haben;
  2. kann sicher entfernt werden.

kann dann <the command above> | xargs git branch -dalle löschen.


42
Diese Antwort ist nicht ganz richtig. Das --pruneFlag löscht nur Fernverfolgungszweige, keine lokalen Zweige.

3
Hier mit @Cupcake einverstanden, erreicht dies nicht das, wonach ich hier suche.
SF89

6
Ich werde nicht upvoten, aber das ist es, was ich brauchte, nachdem ich lokale Zweige gelöscht und dann aus GitHub gelöscht hatte, aber diese noch als Fernbedienungen in meinem git remote -v-Befehl vorhanden waren.
Spechal

8
Sie können auch tun git fetch --prune, das ist meine Art der Wahl
e_m0ney

1
Ein weiterer Git-Fehler aufgrund von Hinweisen zum Stapelüberlauf ... git pull --pruneführte zu "Sie haben gefragt, ob Sie von der Fernbedienung '--prune' abrufen möchten, aber keinen Zweig angegeben. Da dies nicht die standardmäßig konfigurierte Fernbedienung für Ihren aktuellen Zweig ist, haben Sie muss einen Zweig in der Befehlszeile angeben. "
JWW

23

Dies sollte funktionieren, um zu vermeiden, dass die Master- und Entwicklungszweige mit der akzeptierten Lösung gelöscht werden:

git branch --merged | egrep -v "^\*|master|development" | xargs -n 1 git branch -d

16

Für Benutzer von Powershell entspricht dies der obigen Antwort :

git branch -vv | Select-String -Pattern ': gone]' | ForEach-Object{($_ -split "\s+")[1]} | %{ git branch -D $_ }
  1. Filtern Sie alle Zweige, die als weg markiert sind
  2. Rufen Sie git branch -Djeden der gefundenen Zweige an

6

Nichts davon funktionierte für mich. Sie können meine andere Antwort hier sehen: https://stackoverflow.com/a/34969726/550454

Aber im Wesentlichen habe ich dies jetzt in meinem ~/.gitconfig:

[alias]
  prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -d

5

Sehr einfache Lösung: Entfernen Sie Ihr lokales Repo und klonen Sie das Remote-Repo erneut. Mag nicht sehr elegant erscheinen, aber es ist einfach und Sie werden genau verstehen, was Sie tun, ohne Manpages zu lesen :-).


1
Warum so viele Abstimmungen? Ich meine offensichtlich nicht effizient, besonders bei größeren Repos, aber es macht das, was OP verlangt. Gibt es einen anderen Grund, dies nicht zu tun?
3ozän

6
Weil Sie alle Ihre lokalen Niederlassungen, Verstecke, ungezwungenen Verpflichtungen verlieren ... es ist wie mit Dynamit zu fischen.
Sevenseacat

1
Das gleiche passiert, wenn der Laptop, an dem Sie arbeiten, irgendwie beschädigt, verloren oder gestohlen wird. Daher neige ich dazu, lokal nichts Entscheidendes zu behalten. Es scheint mir besser, einfach einen Zweig zu erstellen und ihn zu pushen, selbst für kleine Features, und ihn zu löschen, nachdem er nicht mehr nützlich ist.

2

Ich mache das nur, um zusammengeführte lokale Zweige zu entfernen:

git branch -d $(git branch --merged)

und falls Sie auch nicht vorhandene Trackings entfernen möchten:

git pull --prune

1

Ich habe diesen Einzeiler geschrieben, um alle lokalen Zweige aufzulisten, die keinen entsprechenden entfernten Zweig haben:

diff -u <(git branch|sed 's/..//') <(git branch -r|sed 's/..origin\///')|tail -n +4|sed -n "s/^-//p" -

Danach ist das Löschen dieser lokalen Zweige einfach mit xargs:

diff -u <(git branch|sed 's/..//') <(git branch -r|sed 's/..origin\///')|tail -n +4|sed -n "s/^-//p" -|xargs -r git branch -d

das listet mich masterauch auf, es funktioniert nicht wie erwartet; Seien Sie vorsichtig
Enrico

1

Für den Fall, dass Sie gerade Ihren Zweig zum Master verschoben und zusammengeführt haben, gehen Sie in git bash wie folgt vor:

git branch -d branch_name_to_delete

Wenn Sie sich derzeit in diesem Zweig befinden, werden Sie zum Master zurückgeschoben. An diesem Punkt ziehen Sie mit

git pull

-2

Die abgestimmte Antwort hat das Potenzial, den Master zu löschen. Betrachten Sie das folgende praktische Beispiel.

Ich hatte zwei Feature-Zweige hemen_README und hemen_BASEBOX, die zu Develop zusammengeführt wurden, und dann wurde Develop zu Master zusammengeführt. Die Feature-Zweige hemen_README und hemen_BASEBOX wurden remote gelöscht, wurden jedoch weiterhin lokal angezeigt. Auch ich bin nicht auf Master vor Ort, sondern auf Entwicklung.

In diesem Fall

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                      671ad6c Merged in hemen_README (pull request #1)
        hemen_BASEBOX                a535c0f added global exec paths to puppet manifest
        hemen_README                 ba87489 Updated Readme with considerable details
        master                       8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop       671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/hemen_BASEBOX a535c0f added global exec paths to puppet manifest
        remotes/origin/hemen_README  ba87489 Updated Readme with considerable details
        remotes/origin/master        2f093ce Merged in develop (pull request #3)

Also, wenn ich den obigen Teilbefehl ausführe

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch --merged | grep -v "\*"
        hemen_BASEBOX
        hemen_README
        master

Beachten Sie, dass auch der Master angezeigt wird, der schließlich gelöscht wird.

Auf jeden Fall konnte ich es schaffen. Ich teile Ihnen mein Sitzungsprotokoll mit, wie ich das erreicht habe.

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git remote prune origin --dry-run
    Pruning origin
    URL: git@bitbucket.org:hemenkapadiapublic/vagrant-webdev.git
     * [would prune] origin/hemen_BASEBOX
     * [would prune] origin/hemen_README
    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git remote prune origin 
    Pruning origin
    URL: git@bitbucket.org:hemenkapadiapublic/vagrant-webdev.git
     * [pruned] origin/hemen_BASEBOX
     * [pruned] origin/hemen_README

Ich habe gerade überprüft, wie beschnitten werden soll, und habe es dann beschnitten. Mit Blick auf den Zweigbefehl unten haben wir uns um Fernbedienungen gekümmert

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                671ad6c Merged in hemen_README (pull request #1)
        hemen_BASEBOX          a535c0f added global exec paths to puppet manifest
        hemen_README           ba87489 Updated Readme with considerable details
        master                 8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop 671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/master  2f093ce Merged in develop (pull request #3)

Löschen Sie nun die lokalen Zweige

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -d hemen_BASEBOX 
    Deleted branch hemen_BASEBOX (was a535c0f).
    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -d hemen_README
    Deleted branch hemen_README (was ba87489).

Gut jetzt sind die Zweige wie gewünscht.

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                671ad6c Merged in hemen_README (pull request #1)
        master                 8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop 671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/master  2f093ce Merged in develop (pull request #3)

Natürlich hat es das Potenzial, Master zu löschen. Bitte lesen Sie die Frage sorgfältig durch. Wie ich dort sagte, brauchte ich einen Weg, um die Dinge in meinem Lokal aufzuräumen. Das bedeutet, dass alle Zweige gelöscht werden, die auf der Fernbedienung nicht mehr vorhanden sind. Wenn der Master nicht mehr vorhanden ist, verschwindet er auch auf Ihrem lokalen Computer.
SF89
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.