it-swarm.com.de

So beschneiden Sie lokale Tracking-Zweige, die nicht mehr auf der Fernbedienung vorhanden sind

Mit git remote Prune Origin kann ich die lokalen Verzweigungen entfernen, die sich nicht mehr auf der Fernbedienung befinden.

Ich möchte aber auch lokale Zweigstellen entfernen, die aus diesen entfernten Zweigstellen erstellt wurden (eine Überprüfung, ob sie nicht zusammengefügt sind, wäre Nizza).

Wie kann ich das machen?

522
Alex

Nach dem Beschneiden können Sie die Liste der entfernten Zweige mit git branch -r abrufen. Die Liste der Zweige mit ihrem Fernverfolgungszweig kann mit git branch -vv abgerufen werden. Wenn Sie diese beiden Listen verwenden, können Sie die Fernverfolgungszweige finden, die nicht in der Liste der Fernbedienungen enthalten sind.

Diese Zeile sollte den Trick ausführen (erfordert bash oder zsh, funktioniert nicht mit Standard-Bourne-Shell):

git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep Origin) | awk '{print $1}' | xargs git branch -d

Diese Zeichenfolge ruft die Liste der fernen Verzweigungen ab und übergibt sie über die Standardeingabe an egrep. Und filtert die Zweige mit einem Remote-Tracking-Zweig (mit git branch -vv und filtert nach den Zweigen mit Origin) und erhält dann die erste Spalte dieser Ausgabe, die der Zweigname ist. Schließlich werden alle Zweignamen an den Befehl delete branch übergeben.

Da die Option -d verwendet wird, werden keine Zweige gelöscht, die nicht mit dem Zweig zusammengeführt wurden, in dem Sie sich befinden, als Sie diesen Befehl ausführen.

Denken Sie auch daran, dass Sie git fetch --Prunefirst ausführen müssen, andernfalls werden in git branch -r weiterhin die Remote-Zweige angezeigt.

747
Schleis

Wenn Sie alle lokalen Zweigstellen löschen möchten, die bereits mit master zusammengeführt wurden, können Sie den folgenden Befehl verwenden:

git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d

Mehr Info .

324
jackocnr

Inmitten der Informationen, die von git help fetch präsentiert werden, gibt es diesen kleinen Artikel:

 -p, --Prune
        After fetching, remove any remote-tracking branches which no longer exist on the remote.

Vielleicht suchen Sie nach git fetch -p?

EDIT: Ok, für diejenigen, die diese Antwort 3 Jahre später noch debattieren, hier ein paar weitere Informationen dazu, warum ich diese Antwort präsentierte ...

Erstens sagt das OP, dass sie "auch die lokalen Verzweigungen entfernen wollen, die von den entfernten Verzweigungen erstellt wurden [die nicht mehr auf der entfernten sind]". Dies ist in git nicht eindeutig möglich. Hier ist ein Beispiel.

Nehmen wir an, ich habe ein Repo auf einem zentralen Server und es hat zwei Zweige namens A und B. Wenn ich dieses Repo in mein lokales System klone, hat mein Klon lokale Refs (noch keine tatsächlichen Zweige) mit dem Namen Origin/A und Origin/B. Nehmen wir an, ich mache folgendes:

git checkout -b A Origin/A
git checkout -b Z Origin/B
git checkout -b C <some hash>

Die relevanten Fakten hier sind, dass ich aus irgendeinem Grund entschieden habe, einen Zweig in meinem lokalen Repo zu erstellen, der einen anderen Namen als seinen Ursprung hat, und ich habe auch einen lokalen Zweig, der (noch) nicht im Origin-Repo vorhanden ist.

Nehmen wir nun an, ich entferne sowohl die A- als auch die B-Verzweigung im Remote-Repo und aktualisiere mein lokales Repo (git fetch irgendeines Formulars), wodurch meine lokalen Verweise Origin/A und Origin/B verschwinden. Jetzt hat mein lokales Repo noch drei Zweige, A, Z und C. Keiner von diesen verfügt über einen entsprechenden Zweig im Remote-Repo. Zwei davon wurden "aus ... entfernten Zweigen erstellt", aber selbst wenn ich weiß, dass es im Ursprung einen Zweig namens B gab, kann ich nicht wissen, dass Z aus B erstellt wurde, da er in umbenannt wurde der Prozess wahrscheinlich aus gutem Grund. Ohne externe Prozessaufzeichnungs-Origin-Metadaten oder einen Menschen, der die Historie kennt, ist es also unmöglich zu sagen, auf welchen der drei Zweige sich das OP, falls überhaupt, zu entfernen beabsichtigt. Ohne einige externe Informationen, die git nicht automatisch für Sie speichert, ist git fetch -p so nahe wie möglich, und bei jeder automatischen Methode, bei der versucht wird, wörtlich zu versuchen, was das OP verlangt, besteht die Gefahr, dass entweder zu viele Verzweigungen gelöscht werden oder das OP nicht vorhanden ist möchte sonst gelöscht werden.

Es gibt auch andere Szenarien, zum Beispiel, wenn ich aus Origin/A drei separate Zweige erstelle, um drei verschiedene Ansätze für etwas zu testen, und dann Origin/A wegfällt. Jetzt habe ich drei Zweige, die offensichtlich nicht alle mit dem Namen übereinstimmen können, aber sie wurden aus Origin/A erstellt. Daher müssten bei einer wörtlichen Interpretation der OP-Frage alle drei entfernt werden. Dies kann jedoch nicht wünschenswert sein, wenn Sie sogar einen zuverlässigen Weg finden könnten, um sie zu finden ...

130
twalberg

Dadurch werden die lokalen Zweige gelöscht, für die die entfernten Verfolgungszweige entfernt wurden. (Stellen Sie sicher, dass Sie sich im Zweig master befinden!)

git checkout master
git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -d

Einzelheiten: 

  • git branch -vv zeigt "gegangen" für lokale Zweigstellen an, für die die Fernbedienung gelöscht wurde.

    mybranch abc1234 [Origin/mybranch: gone] commit comments
    
  • -d prüft, ob es zusammengeführt wurde (-D löscht es trotzdem)

    error: The branch 'mybranch' is not fully merged.
    
88
wisbucky

Man kann Git so konfigurieren, dass beim Abrufen automatisch Verweise auf gelöschte entfernte Zweige entfernt werden:

git config --global fetch.Prune true

Beim nachfolgenden Aufruf von git fetch oder git pull werden Verweise auf gelöschte entfernte Zweige automatisch entfernt.

38
wedesoft

Windows-Lösung

Für Microsoft Windows PowerShell:

git checkout master; git remote update Origin --Prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}

Erklärung

git checkout master Wechselt in den Master-Zweig

git remote update Origin --Prune Schneidet entfernte Zweige ab

git branch -vv Liefert eine ausführliche Ausgabe aller Zweige ( git reference )

Select-String -Pattern ": gone]" Ruft nur die Datensätze ab, von denen sie entfernt wurden.

% { $_.toString().Split(" ")[0]} Ermittelt den Filialnamen

% {git branch -d $_} Löscht den Zweig

25
chris31389

Es werden die lokalen Zweigstellen aufgelistet, deren entfernter Tracking-Zweig aus der entfernten gelöscht wird

$ git remote Prune Origin --dry-run

Wenn Sie diese lokalen Verzweigungen von lokalen entfernen möchten, die nicht verfolgt werden

$ git remote Prune Origin
21
027

Es gibt ein nettes 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 Niederlassungen und git removed-branches --Prune, um sie tatsächlich zu löschen.

Mehr Infos hier.

20
tzachs

Wenn Sie Windows und Powershell verwenden, können Sie mit dem folgenden Befehl alle lokalen Zweige löschen, die in den aktuell ausgecheckten Zweig eingefügt wurden:

git branch --merged | ? {$_[0] -ne '*'} | % {$_.trim()} | % {git branch -d $_}

Erläuterung

  • Listet den aktuellen Zweig und die darin zusammengeführten Zweige auf
  • Filtert den aktuellen Zweig aus
  • Bereinigt alle führenden oder nachgestellten Leerzeichen aus der git-Ausgabe für jeden verbleibenden Zweignamen
  • Löscht die zusammengeführten lokalen Zweigstellen

Es lohnt sich, zuerst git branch --merged auszuführen, nur um sicherzustellen, dass nur das entfernt wird, was Sie erwarten.

(Portiert/automatisiert von http://railsware.com/blog/2014/08/11/git-Housekeeping-tutorial-clean-up-outdated-branches-in-local-und-remote-repositories/ . )

15
Gnat

Ich wollte etwas, das alle lokalen Zweige, die einen entfernten Zweig aufspürten, auf Origin löscht, wo der entfernte Zweig gelöscht wurde (gone). Ich wollte keine lokalen Zweigstellen löschen, die niemals so eingerichtet waren, dass sie einen entfernten Zweig verfolgen (d. H .: meine lokalen Dev-Zweigstellen). Außerdem wollte ich einen einfachen Einzeiler, der nur git oder andere einfache CLI-Tools verwendet, anstatt benutzerdefinierte Skripts zu schreiben. Am Ende benutzte ich etwas grep und awk, um diesen einfachen Befehl zu erstellen, und fügte ihn dann als Alias ​​in meinen ~/.gitconfig ein. 

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

Hier ist ein git config --global ...-Befehl zum einfachen Hinzufügen als git Prune-branches:

git config --global alias.Prune-branches '!git remote Prune Origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d'

HINWEIS: Die Verwendung des Flags -D für git branch kann sehr gefährlich sein. Im obigen Befehl config verwende ich die -d-Option für git branch und nicht für -D. Ich verwende -D in meiner aktuellen Konfiguration. Ich benutze -D, weil ich nicht hören möchte, dass Git über nicht zusammengeführte Zweige klagt. Ich möchte nur, dass sie verschwinden. Möglicherweise möchten Sie auch diese Funktionalität. Wenn ja, verwenden Sie einfach -D anstelle von -d am Ende dieses Konfigurationsbefehls.

7
Karl Wilbur

Noch kürzer und sicherer One-Liner:

git branch -d $(git branch --merged | cut -c 3-)

Vergewissern Sie sich vor dem Ausführen, dass Sie zu einem Zweig wechseln, der noch nicht zusammengeführt wurde. Sie können den Zweig, den Sie gerade eingecheckt haben, nicht löschen.

5
FelikZ

nicht sicher, wie das alles auf einmal zu tun ist, aber git git branch -d <branchname> löscht NUR einen lokalen Zweig, wenn er vollständig zusammengefügt ist. Beachten Sie das Kleinbuchstabe d.

git branch -D <branchname> (beachten Sie das Großbuchstabe D), wird eine lokale Zweigstelle unabhängig von ihrem zusammengeführten Status gelöscht.

4
NHDaly

Um entfernte Zweige zu entfernen

$git remote Prune Origin

So entfernen Sie lokale Zweige, die bereits zusammengeführt wurden

$git branch -D $(git branch --merged)
2
Aniket

Basierend auf den obigen Antworten kam ich mit dieser einzeiligen Lösung:

git remote Prune Origin; git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep Origin) | awk '{print $1}' | xargs git branch -d
2
gagarwal

Sie können diesen Befehl verwenden:

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

Git Clean: Löschen Sie bereits zusammengefügte Zweige einschließlich der Aufschlüsselung des Befehls

2
sendon1982

Mit einer Variante von @ wisbuckys Antwort fügte ich meiner ~/.gitconfig-Datei Folgendes als Alias ​​hinzu:

pruneitgood = "!f() { \
    git remote Prune Origin; \
    git branch -vv | Perl -nae 'system(qw(git branch -d), $F[0]) if $F[3] eq q{gone]}'; \
}; f"

Mit diesem einfachen git pruneitgood werden sowohl lokale als auch entfernte Zweige entfernt, die nach dem Zusammenführen nicht mehr benötigt werden.

2
Ken Williams

Basierend auf den obigen Antworten verwende ich diesen kürzeren Liner:

git remote Prune Origin | grep pruned | awk 'BEGIN{FS="/"} ; { print $2 }' | xargs git branch -d
1
hidralisk

Schleis 'Variante funktioniert nicht für mich (Ubuntu 12.04), also lassen Sie mich meine (klare und glänzende :) Variante vorschlagen:

Variante 1 (Ich würde diese Option vorziehen):

git for-each-ref --format='%(refname:short) %(upstream)' refs/heads/ | awk '$2 !~/^refs\/remotes/' | xargs git branch -D 

Variante 2:

ein. Probelauf:

comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | awk '{print "git branch -D " $1}'

b. Zweige entfernen:

comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | xargs git branch -D
1
daniilyar

Ich habe aus der akzeptierten Antwort ein robustes Skript gemacht. Sie finden es in meinem Repository für Git-Erweiterungen .

$ git-Prune --help
Remove old local branches that do not exist in <remote> any more.
With --test, only print which local branches would be deleted.
Usage: git-Prune [-t|--test|-f|--force] <remote>
1
Ingo Karkat

Es scheint keinen sicheren Einzeiler zu geben, zu viele Edge-Fälle (wie ein Zweig mit "Master" als Teil seines Namens usw.) Am sichersten sind diese Schritte: 

  1. git branch -vv | grep 'gone]' > stale_branches.txt 
  2. die Datei anzeigen und Zeilen für Zweige entfernen, die Sie behalten möchten (z. B. Hauptzweig!); Sie müssen den Inhalt einer Zeile nicht bearbeiten
  3. awk '{print $1}' stale_branches.txt | xargs git branch -d
1
Oliver

Versuchen Sie dies in git bash, um Verweise auf gelöschte Verzweigungen abzurufen und zu beschneiden, und beschneiden Sie dann die lokalen Verzweigungen, die die entfernten verfolgten:

git fetch -p && git branch -d `git branch -vv | grep ': gone]' | awk '{print $1}' | xargs`

Denken Sie daran, zuerst einen Zweig zu checken, der nicht gelöscht wird, damit das Löschen des Zweigs nicht blockiert wird.

Es folgt eine Anpassung der Antwort von @ wisbucky für Windows-Benutzer:

for /f "tokens=1" %i in ('git branch -vv ^| findstr ": gone]"') DO git branch %i -d

Ich benutze posh-git und leider mag PS das nackte for nicht, also habe ich ein einfaches Befehlsskript namens PruneOrphanBranches.cmd erstellt:

@ECHO OFF
for /f "tokens=1" %%i in ('git branch -vv ^| findstr ": gone]"') DO CALL :ProcessBranch %%i %1

GOTO :EOF

:ProcessBranch
IF /I "%2%"=="-d" (
    git branch %1 %2
) ELSE (
    CALL :OutputMessage %1
)
GOTO :EOF

:OutputMessage
ECHO Will delete branch [%1] 
GOTO :EOF

:EOF

Rufen Sie es ohne Parameter auf, um eine Liste anzuzeigen, und rufen Sie es dann mit "-d" auf, um das eigentliche Löschen durchzuführen, oder "-D" für alle Zweige, die nicht vollständig zusammengeführt sind, die Sie jedoch trotzdem löschen möchten.

1
Sam C

Die Powershell-Version von git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d

git branch --merged master | %{ if($_ -notmatch '\*.*master'){ git branch -d "$($_.Trim())" }}

Dadurch werden alle lokalen Zweige entfernt, die in master zusammengeführt wurden während Sie sich im master-Zweig befinden.

git checkout master Zum Umschalten.

1
Kevin George

Ich habe auf dieser Seite nach der Antwort für "Wie lösche ich lokal ausgecheckte Zweige, die keinen Upstream-Zweig mehr haben" gesucht.

Mir war es auch egal, ob die lokale Niederlassung schon zusammengeführt wurde oder nicht, da die Weiterleitung in git branch -d einfach warnt, anstatt nicht zusammengeführte lokale Niederlassungen zu löschen.

git branch -a | grep Origin | tr -s ' ' | cut -d '/' -f3 | egrep -v -f /dev/fd/0 <(git branch -a | grep -v Origin) | grep branch_prefix_that_I_care_about | xargs git branch -d

# translation
# git branch -a | grep Origin | tr -s ' ' | cut -d '/' -f3
## this finds all remote branch names minus the "remote/Origin/" part
#
# <(git branch -a | grep -v Origin)
## this finds all local branch names and redirects it into the previous command
#
# egrep -v -f /dev/fd/0 STUFF
## this is doing some weird magic that I'm grokking as "take the set difference from whatever was piped in"
#
#
# overall translation: (STUFF TO CONSIDER) | egrep magic <(STUFF TO REMOVE FROM CONSIDERATION) | do cool things with resulting stuff
0
Meredith