wake-up-neo.com

Alle lokalen Niederlassungen ohne Remote auflisten

Problem: Ich möchte alle lokalen Zweigstellen löschen, die keine Fernbedienung haben. Es ist leicht genug, die Namen der Zweige in einen git branch -D {branch_name} zu pfeifen, aber wie bekomme ich diese Liste überhaupt?

Zum Beispiel:

Ich erstelle einen neuen Zweig ohne Fernbedienung:

$ git co -b no_upstream

Ich liste alle meine Filialen auf, es gibt nur eine mit einer Fernbedienung

$ git branch -a
master
* no_upstream
remotes/Origin/HEAD -> Origin/master
remotes/Origin/master

Welchen Befehl kann ich ausführen, um no_upstream als Antwort zu erhalten?

Ich kann git rev-parse --abbrev-ref --symbolic-full-name @{u} ausführen und das wird zeigen, dass es keine Fernbedienung hat:

$ git rev-parse --abbrev-ref --symbolic-full-name @{u}
error: No upstream configured for branch 'no_upstream'
error: No upstream configured for branch 'no_upstream'
fatal: ambiguous argument '@{u}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

Da dies jedoch ein Fehler ist, kann ich ihn nicht verwenden oder an andere Befehle weiterleiten. Ich beabsichtige, dies entweder als Shell-Skript-Alias ​​zu git-delete-unbranched zu verwenden oder vielleicht einen super einfachen Gem zu machen, wie git-branch-delete-orphans

Jede Hilfe wäre dankbar! Vielen Dank

54
JC Denton

Ich habe kürzlich git branch -vv entdeckt, die die "sehr ausführliche" Version des git branch-Befehls ist.

Sie gibt die Verzweigungen zusammen mit den entfernten Verzweigungen, sofern vorhanden, im folgenden Format aus:

  25-timeout-error-with-many-targets    206a5fa WIP: batch insert
  31-target-suggestions                 f5bdce6 [Origin/31-target-suggestions] Create target suggestion for team and list on save
* 54-feedback-link                      b98e97c [Origin/54-feedback-link] WIP: Feedback link in mail
  65-digest-double-publish              2de4150 WIP: publishing-state

Sobald Sie diese schön formatierte Ausgabe haben, können Sie sie einfach durch cut und awk leiten, um Ihre Liste zu erhalten:

git branch -vv | cut -c 3- | awk '$3 !~/\[/ { print $1 }'

Ergebnisse in der folgenden Ausgabe:

25-timeout-error-with-many-targets
65-digest-double-publish

Der cut-Teil normalisiert die Daten nur, indem die ersten beiden Zeichen (einschließlich *) aus der Ausgabe entfernt werden, bevor sie an awk übergeben werden. 

Der Abschnitt awk gibt die erste Spalte aus, wenn die dritte Spalte keine eckige Klammer enthält.

Bonus: Erstelle einen Alias ​​

Machen Sie es einfach, indem Sie einen Alias ​​in Ihrer globalen .gitconfig-Datei (oder wo auch immer) erstellen:

[alias]
  local-branches = !git branch -vv | cut -c 3- | awk '$3 !~/\\[/ { print $1 }'

Wichtig: Der Backslash muss im Alias ​​mit Escapezeichen versehen sein, andernfalls erhalten Sie eine ungültige gitconfig-Datei.

Bonus: Fernfilterung

Wenn Sie aus verschiedenen Gründen mehrere Tracking-Fernbedienungen für verschiedene Zweige haben, können Sie einfach angeben, mit welcher Fernbedienung Sie prüfen möchten. Hängen Sie einfach den Namen der Fernbedienung an das awk-Muster an. In meinem Fall ist es Origin, also kann ich folgendes tun:

git branch -vv | cut -c 3- | awk '$3 !~/\[Origin/ { print $1 }'
64
Jeremy Baker

git branch (ohne Optionen) listet nur lokale Zweige auf, aber Sie wissen nicht, ob sie einen entfernten Zweig verfolgen oder nicht.

Normalerweise sollten diese lokalen Zweigstellen gelöscht werden, sobald sie mit master zusammengefügt wurden (wie in dieser Ausgabe von git-sweep ):

git branch --merged master | grep -v master | xargs git branch -d

Dies ist nicht so vollständig, wie Sie möchten, aber es ist ein Anfang.

Mit --merged werden nur Zweige aufgelistet, die mit dem genannten Commit zusammengeführt werden (d. H. Die Zweige, deren Tipp-Commits mit dem genannten Commit erreichbar sind).

24
VonC

Ich habe ein ähnliches Problem. Ich möchte alle lokalen Zweige entfernen, die entfernte Zweige verfolgten, die jetzt gelöscht werden. Ich finde, dass git remote Prune Origin hat nicht ausgereicht, um die Zweige zu entfernen, die ich entfernen möchte. Sobald die Fernbedienung gelöscht ist, möchte ich, dass die lokale ebenfalls verschwindet. Folgendes hat bei mir funktioniert:

Von meinem ~/.gitconfig:

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

BEARBEITEN: Wie gewünscht, 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'

[~ # ~] note [~ # ~]: Ich habe das -d bis -D in meiner aktuellen Konfiguration, weil ich nicht hören möchte, wie sich Git über nicht zusammengeführte Zweige beschwert. Sie möchten may auch diese Funktionalität. Wenn ja, benutze einfach -D anstatt -d am Ende dieses Befehls.

Außerdem, FWIW, wäre Ihre globale Konfigurationsdatei fast immer ~/.gitconfig.

EDIT: (OSX Fix) Wie geschrieben, funktioniert dies unter OSX nicht, da xargs -r (danke, Korny ).

Das -r soll verhindern, dass xargs ausgeführt wird git branch -d ohne Verzweigungsnamen, was zu einer Fehlermeldung "fatal: branch name required ". Wenn Ihnen die Fehlermeldung nichts ausmacht, können Sie einfach den -r Argument zu xargs und fertig.

Wenn Sie jedoch keine Fehlermeldung sehen möchten (und wirklich, wer könnte Ihnen die Schuld geben), benötigen Sie etwas anderes, das nach einer leeren Pipe sucht. Wenn Sie in der Lage sein könnten, ifne from moreutils zu verwenden. Sie würden ifne vor xargs einfügen, wodurch verhindert wird, dass xargs mit leeren Daten ausgeführt wird. [~ # ~] note [~ # ~]: ifne betrachtet alles als nicht leer, dies schließt leere Zeilen ein, so dass diese Fehlermeldung möglicherweise weiterhin angezeigt wird. Ich habe dies nicht unter OSX getestet.

Hier ist das git config Zeile mit ifne:

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

Späte Bearbeitung: besser ist es 

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

auf GNU/irgendetwas

for b in `git branch|sed s,..,,`; do
    git config --get branch.$b.remote|sed Q1 && echo git branch -D $b
done

Wenn mehr als eine Handvoll Verzweigungen wahrscheinlich wären, wäre es besser, comm -23 für die Ausgabe von git branch|sed|sort und git config -l|sed|sort zu verwenden.

14
jthill

Das funktioniert für mich:

git branch -vv | grep -v Origin 

(Wenn Ihre Fernbedienung einen anderen Namen als Origin hat, setzen Sie diesen ein).

Daraufhin werden alle Zweige aufgelistet, die keine Fernbedienung verfolgen.

11
ebr

Grobe Powershell-Implementierung: (wenn Origin Ihre einzige Fernbedienung ist)

@($branches = git br -r; git branch | %{ echo $_ | sed 's/..//' }) `
   | %{ if (($branches | ss "Origin/$_") -eq $null) { `
          echo "git branch -D $_" `
        } `
      }
2
nbergen

Hier ist etwas, was ich in PowerShell mit Kommentaren verwendet habe, um zu erklären, was es tut. Um zu verdeutlichen, was los ist, habe ich keine abgekürzten PS-Befehle verwendet. Fühlen Sie sich frei, es auf den gewünschten Grad an Verschlüsselung zu komprimieren :)

$verboseList = @(git br -vv)
foreach ($line in $verboseList)
{    
    #get the branch name
    $branch = [regex]::Match($line, "\s(\S+)\s").Captures.Groups[1].Value
    #check if the line contains text to indicate if the remote is deleted
    $remoteGone = $line.Contains(": gone]")
    #check if the line does not contain text to indicate it is a tracking branch (i.e., it's local)
    $isLocal = !($line.Contains("[Origin/"))
    if ($remoteGone -or $isLocal)
    {
        #print the branch name
        $branch
    }
}
2
grahamesd

Ich sinthetize meinen eigenen git-Befehl, um die Origin/***: gone-Verzweigungen zu erhalten:

git remote Prune Origin && git branch -vv | cut -c 3- | grep ': gone]' | awk '{print $1}' | xargs -n1 -r echo git branch -d

git remote Prune Origin && git branch -vv druckt Zweige im ausführlichen Modus

cut -c 3- entfernt die ersten Zeichen

grep ': gone]' druckt nur die entfernten Zweigstellen gone  

awk '{print $1}' druckt den Zweignamen

xargs -n1 -r echo git branch -d gibt den Befehl git branch -d aus, um Verzweigungen zu entfernen (-n1 verwaltet jeweils einen Befehl, -r, um die Ausgabe eines Befehls zu vermeiden, wenn keine Verzweigung vorhanden ist.)

TIPP: Entfernen Sie den Befehl "echo", um run die Befehle auszuführen, anstatt nur zu drucken. Ich habe dies im Befehl gelassen, um die Befehle zu überprüfen, bevor Sie git ausgeben.

TIPP 2: issue git branch -D wenn und nur dann, wenn Sie sicher sind, dass Sie nicht zusammengeführte Zweige entfernen möchten

0
fiorentinoing