Verfolgen Sie alle Remote-Git-Zweige als lokale Zweige

175

Das Verfolgen eines einzelnen Remote-Zweigs als lokaler Zweig ist recht einfach.

$ git checkout --track -b ${branch_name} origin/${branch_name}

Es ist auch einfach, alle lokalen Zweige auf die Fernbedienung zu verschieben und bei Bedarf neue Fernzweige zu erstellen.

$ git push --all origin

Ich möchte das Gegenteil tun. Wenn ich X Anzahl von Remote-Zweigen an einer einzigen Quelle habe:

$ git branch -r 
branch1
branch2
branch3
.
.
.

Kann ich lokale Tracking-Zweige für alle diese Remote-Zweige erstellen, ohne dass jeder manuell erstellt werden muss? Sagen Sie etwas wie:

$ git checkout --track -b --all origin

Ich habe gegoogelt und RTMs, bin aber bisher in die Koje gekommen.

Janson
quelle
3
Es gibt eine noch einfachere Möglichkeit, einen einzelnen Remote-Zweig als lokalen Zweig zu verfolgen:git checkout --track origin/branchname
Cerran
Dies ist nicht genau das, wonach Sie gefragt haben, aber es funktioniert für mich: Holen Sie sich Git-Vervollständigungen: github.com/git/git/blob/master/contrib/completion/… . Geben Sie dann ein git pull origin und drücken Sie tab, um eine Liste der entfernten Zweige zu erhalten. Dann tippen Sie weiter und drücken Sie return.
Max Heiber

Antworten:

111

Bash verwenden:

nach git 1.9.1
for i in `git branch -a | grep remote | grep -v HEAD | grep -v master`; do git branch --track ${i#remotes/origin/} $i; done

Credits: Val Blant, Elias und Hugo

vor git 1.9.1

Hinweis: Der folgende Code verursacht, wenn er in späteren Versionen von git (> v1.9.1) verwendet wird

  1. (Fehler) Alle erstellten Zweige, um den Master zu verfolgen
  2. (Ärger) Alle erstellten lokalen Filialnamen, denen ein Präfix vorangestellt werden soll origin/
for remote in `git branch -r `; do git branch --track $remote; done

Aktualisieren Sie die Zweige, vorausgesetzt, es gibt keine Änderungen an Ihren lokalen Tracking-Zweigen:

for remote in `git branch -r `; do git checkout $remote ; git pull; done

Ignorieren Sie die mehrdeutigen Refname-Warnungen. Git scheint den lokalen Zweig so zu bevorzugen, wie er sollte.

Otto
quelle
2
Vielen Dank für das Heads-up zu den Refname-Warnungen. Das war hilfreich.
Paul
1
Danke Otto, ich vermutete, dass Scripting die einzige Lösung sein würde. Sie haben eine ziemlich einfache bereitgestellt.
Janson
1
@ Jason ist es noch heute die einzige Lösung für Skripte?
Cregox
1
@Cawas: Sie müssen Tracking-Zweige manuell erstellen, haben jedoch git pulleinen --allSchalter, mit dem alle verfolgten Zweige abgerufen und zusammengeführt werden .
naught101
13
Dies hat bei Git 1.9.1 bei mir nicht funktioniert. "git branch --track <Banchenname>" erstellt einen neuen Zweig <branch_name>, der den lokalen Zweigmaster anstelle des gewünschten Remote-Zweigs verfolgt. Dieses Skript hat also eine Reihe lokaler Zweige erstellt, die alle auf den lokalen Master verweisen. Ich werde die Lösung unten posten.
Val Blant
183

Die Antwort von Otto ist gut, aber alle erstellten Zweige haben "Ursprung /" als Anfang des Namens. Wenn Sie nur möchten, dass der letzte Teil (nach dem letzten /) Ihre resultierenden Zweignamen sind, verwenden Sie Folgendes:

for remote in `git branch -r | grep -v /HEAD`; do git checkout --track $remote ; done

Es hat auch den Vorteil, dass Sie keine Warnungen vor mehrdeutigen Verweisen erhalten.

tjmcewan
quelle
Git fügt dem Namen des lokalen Tracking-Zweigs keinen "Ursprung" hinzu.
Adam Dymitruk
14
@adymitruk: Eigentlich verhält es sich genau so, wie ich es unter OSX 10.6.4 für mich gesagt habe, unter Verwendung von Git 1.7.2.2 (der neueste Stall ab diesem Kommentar). Otto erwähnt sogar mehrdeutige Refname-Warnungen - die Warnungen müssten nicht existieren, wenn "origin /" nicht Teil jedes lokalen Filialnamens wäre. Hier ist die Ausgabe des 'Git-Zweigs', nachdem Ottos Befehl ausgeführt wurde: [Master, Ursprung / KOPF, Ursprung / Diagramme, Ursprung / Master, Ursprung / Produktion, Ursprung / Inszenierung]. Und mein Befehl: [Charts, Master, Produktion, Inszenierung].
Tjmcewan
1
+ Bearbeiten: gefunden article.gmane.org/gmane.comp.version-control.git/112575 erklärt warum.
Philip Oakley
8
Ich stimme zu - dies ist eine bessere Lösung als die derzeit "akzeptierte" Antwort.
tobias.mcnulty
2
Anstatt grep -v masterwie wäre es grep -v /HEAD? Dies scheint den Standardzweig herauszufiltern, ohne dass eine Anpassung erforderlich ist
dashrb
22

Die meisten Antworten hier erschweren das Parsen der Ausgabe von git branch -r. Sie können Folgendes verwendenfor Schleife die Tracking-Zweige wie für alle Zweige auf der Fernbedienung erstellen.

Beispiel

Angenommen, ich habe diese entfernten Zweige.

$ git branch -r
  origin/HEAD -> origin/master
  origin/development
  origin/integration
  origin/master
  origin/production
  origin/staging

Stellen Sie sicher, dass wir lokal noch nichts anderes als den Master verfolgen:

$ git branch -l    # or using just git branch
* master

Mit diesem einen Liner können Sie die Tracking-Zweige erstellen:

$ for i in $(git branch -r | grep -vE "HEAD|master"); do 
    git branch --track ${i#*/} $i; done
Branch development set up to track remote branch development from origin.
Branch integration set up to track remote branch integration from origin.
Branch production set up to track remote branch production from origin.
Branch staging set up to track remote branch staging from origin.

Bestätigen Sie nun:

$ git branch
  development
  integration
* master
  production
  staging

So löschen Sie sie:

$ git br -D production development integration staging 
Deleted branch production (was xxxxx).
Deleted branch development (was xxxxx).
Deleted branch integration (was xxxxx).
Deleted branch staging (was xxxxx).

Wenn Sie den -vvSchalter verwenden, können git branchSie Folgendes bestätigen:

$ git br -vv
  development xxxxx [origin/development] commit log msg ....
  integration xxxxx [origin/integration] commit log msg ....
* master      xxxxx [origin/master] commit log msg ....
  production  xxxxx [origin/production] commit log msg ....
  staging     xxxxx [origin/staging] commit log msg ....

Aufschlüsselung der for-Schleife

Die Schleife ruft im Grunde den Befehl auf git branch -rund filtert mit HEAD oder Master-Zweigen in der Ausgabe heraus grep -vE "HEAD|master". Um nur die Namen der Zweige abzüglich der origin/Teilzeichenfolge zu erhalten, verwenden wir die String-Manipulation von Bash ${var#stringtoremove}. Dadurch wird die Zeichenfolge "stringtoremove" aus der Variablen entfernt $var. In unserem Fall entfernen wir die Zeichenfolge origin/aus der Variablen $i.

HINWEIS: Alternativ können git checkout --track ...Sie dies auch verwenden:

$ for i in $(git branch -r | grep -vE "HEAD|master" | sed 's/^[ ]\+//'); do 
    git checkout --track $i; done

Diese Methode interessiert mich jedoch nicht besonders, da sie Sie beim Auschecken zwischen den Zweigen wechselt. Wenn Sie fertig sind, bleiben Sie auf dem letzten Zweig, den es erstellt hat.

Verweise

slm
quelle
1
Funktioniert perfekt mit Git Version 2.3.2 (Apple Git-55)
AndrewD
22

Update Q1 2020: Mohsen Abasi schlägt in den Kommentaren auf der Grundlage der Antwort des slm 2014 die einfachere Alternative vor:

for i in $(git branch -r | grep -vE "HEAD|master" | sed 's/^[ ]\+//'); 

Und es werden $()anstelle veralteter Backticks verwendet .

Wie ich in erwähnen eine andere alte Antwort , mit git for-each-refist wahrscheinlich schneller .
Und ich würde den neuen git switchBefehl (Git 2.23+) verwenden , der die Verwirrung ersetztgit checkout .

for i in $(git for-each-ref --format=%(refname:short) \
  --no-merged=origin/HEAD refs/remotes/origin); do \
    git switch --track $i; \
done

Auf diese Weise nicht grepbenötigt.


Alte (2011) ursprüngliche Antwort:

Hier ist mein Einzeiler, den ich benutze (in einer Bash-Shell, getestet mit msysgit1.7.4):

Zum Kopieren und Einfügen:

remote=origin ; for brname in `git branch -r | grep $remote | grep -v master | grep -v HEAD | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do git branch --set-upstream-to $remote/$brname $brname; done

Für mehr Lesbarkeit:

remote=origin ; // put here the name of the remote you want
for brname in `
    git branch -r | grep $remote | grep -v master | grep -v HEAD 
    | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'
`; do 
    git branch --set-upstream-to $remote/$brname $brname; 
done
  • Es werden nur Upstream-Zweige von der Fernbedienung ausgewählt, die Sie in der remoteVariablen angegeben haben (es kann 'origin ' sein oder ein beliebiger Name, den Sie für eine der Fernbedienungen Ihres aktuellen Git-Repos festgelegt haben).
  • Es wird den Namen des Zweigs extrahieren: origin/a/Branch/Name => a/Branch/Namedurch den awkAusdruck.
  • Der Upstream-Zweig wird durch --set-upstream-to(oder -u) gesetzt , nicht --track:
    Der Vorteil ist, dass der Zweig, wenn er bereits vorhanden ist, nicht fehlschlägt und den Ursprung des Zweigs nicht ändert, sondern nur die branch.xxx.(remote|merge)Einstellung konfiguriert .

    branch.aBranchName.remote=origin
    branch.aBranchName.merge=refs/heads/a/Branch/Name
    

Dieser Befehl erstellt lokale Zweige für alle Remote-Upstream-Zweige und setzt deren Remote- und Zusammenführungseinstellung auf diesen Remote-Zweig.

VonC
quelle
5
Dies gibt mir "fatal: Zweig 'was auch immer' existiert nicht" für jeden Zweig, der nur auf der Fernbedienung existiert und keinen entsprechenden lokalen Zweig hat.
Chris Dodd
Ich denke, wenn ein Filialname / zum Beispiel enthält: feature / rc-41-bckend, funktioniert diese Lösung nicht !!!!
Mohsen Abasi
@VonC Basierend auf der Antwort von "slm": $ für i in $ (git branch -r | grep -vE "HEAD | master" | sed 's / ^ [] \ + //'); git checkout --track $ i; fertig
Mohsen Abasi
@MohsenAbasi Sieht gut aus. In meiner Antwort erwähnte ich die Verwendung von --set-upstream-toanstatt von --trackobwohl.
VonC
@MohsenAbasi Ich habe Ihre Alternative in die Antwort für mehr Sichtbarkeit aufgenommen. Ich habe eine andere Möglichkeit hinzugefügt, entfernte Zweige aufzulisten und git switchstattdessen zu verwenden git checkout. Aber deine (sehr gute) Idee bleibt.
VonC
14

Sie könnten das leicht genug schreiben, aber ich weiß nicht, wann es wertvoll sein würde. Diese Zweige würden ziemlich schnell zurückfallen, und Sie müssten sie ständig aktualisieren.

Die Remote-Zweige werden automatisch auf dem neuesten Stand gehalten. Daher ist es am einfachsten, den lokalen Zweig an der Stelle zu erstellen, an der Sie tatsächlich daran arbeiten möchten.

Dustin
quelle
2
Das ist ein guter Punkt. Der Hauptanwendungsfall, an den ich denke, ist das Einrichten einer lokalen Entwicklungsumgebung basierend auf einem Remote-Git-Repository. Wenn ich also meinen ersten Klon mache, möchte ich auch alle Remote-Zweige so verfolgen, wie sie zu diesem Zeitpunkt sind.
Janson
1
Das Handy git upaktualisiert alle lokalen Filialen.
Hugo
9
for i in `git branch -a | grep remote`; do git branch --track ${i#remotes/origin/} $i; done
Val Blant
quelle
4
Ich musste | grep -v HEADder Pipeline ein hinzufügen , damit es richtig funktioniert.
Elias Dorneles
9

ohne Scripting (in einem leeren Verzeichnis):

$ git clone --bare repo_url .git
$ git config core.bare false
$ git checkout

Danach werden alle Remote-Zweige als lokal angesehen.


Original (auf Russisch) .

aleksandr barakin
quelle
Dies ist bei weitem die einfachste Lösung und hat für mich am 2.21.0.windows.1
Rotsiser Mho
7

Wenn Sie Powershell verwenden möchten und Ihre Fernbedienung als Ursprung bezeichnet wird. Dann funktioniert das.

git fetch    
git branch -r  | %{$_ -replace "  origin/"} | %{git branch --track $_ "origin/$_"}
BigMiner
quelle
Das war super hilfreich, ich habe eine kleine Variation verwendet, damit es mit meinem git svn clone'dRepo funktioniert :git branch -r | %{$_ -replace " origin/"} | %{git checkout -b $_ "origin/$_"}
Nate
Ich habe auch eine kleine Änderung vorgenommen, weil meine lokalen Niederlassungen bereits existieren:git branch -r | %{$_ -replace " origin/"} | %{git branch -u "origin/$_" $_}
ch271828n
3
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do  git branch --track ${branch##*/} $branch; done

Verwenden Sie diese Option, und Sie erhalten keine Warnung wie: refname 'origin / dev' ist nicht eindeutig

Bruziuz
quelle
3

Hier ist meine Lösung des BASH-Befehls, auf den @tjmcewan verweist:

for remote in `git branch -r | grep -v /HEAD `; do git branch --track ${remote/"origin/"/""}; done

Mein Ziel ist es, das Problem zu lösen, dass alle erstellten Zweige "origin /" als Anfang des Namens haben, da ich getestet habe, dass $ remote-Variablen immer noch "origin /" enthalten:

for remote in `git branch -r | grep -v /HEAD`; do echo $remote ; done
Nick Tsai
quelle
Nachdem ich @tjmcewans BASH getestet hatte, stellte ich fest, dass der Name aller verfolgten Zweige ohne 'origin /' auf local liegt. Ich weiß nicht warum.
Nick Tsai
1
Der erste Befehl erstellt Brances, die "Master" verfolgen. Das ist nicht das Zeug, das die meisten Leute wollen.
Alexei Osipov
@AlexeiOsipov Danke!
Nick Tsai
2

Rufen Sie dies aus einer Batch-Datei auf, um dasselbe wie die Antwort von tjmcewan unter Windows zu tun :

for /f "delims=" %%r in ('git branch -r ^| grep -v master') do git checkout --track %%r

Oder dies über die Kommandozeile :

for /f "delims=" %r in ('git branch -r ^| grep -v master') do git checkout --track %r
Hugo
quelle
1

Ab Git 2.23:

for branch in `git branch -r | grep origin/`; do git switch -t -C ${branch#origin/} $branch; git pull; done

Das -CFlag zum git switchErstellen oder Zurücksetzen, falls es bereits vorhanden ist.

Git Switch Dokumentation

AeroX
quelle
0

Falls Sie bereits einige Filialen ausgecheckt haben und möchten

  • Überprüfen Sie alle verbleibenden Zweige von der Fernbedienung
  • Stellen Sie sicher, dass alle lokalen Zweige die entfernten Zweige verfolgen

Sie können das folgende bash- und zsh-kompatible Skript verwenden:

git branch -r | while read b; do if git branch | grep -q " ${b##*/}$"; then git branch --set-upstream ${b##*/} $b; else git branch --track ${b##*/} $b; fi; done
Simonair
quelle
0
for rembranch in `git remote update 2>&1 > /dev/null ; git branch -r|egrep -wv "HEAD|master"`
do 
    git checkout --track -b `echo $rembranch|awk -F\/ '{print $2}'` $rembranch; 
done

Erläuterung:

Zeile 1: 'git branch -r' (gefolgt von 'git remote update', um die Informationen zu Änderungen an remote zu aktualisieren) listet alle Remote-Zweige auf; 'egrep -vw' wird verwendet, um Einträge mit HEAD und Master im Ergebnis anzuklopfen.

Zeile 3: Verfolgen Sie den benannten Remote-Zweig, während Sie ihn lokal auschecken. Ein einfaches awk wird verwendet, um zu vermeiden, dass 'origin /' das Suffix für lokale Zweige ist.

ksvrgh
quelle
0

Wenn Sie mit bash alle Zweige auschecken möchten:

for remote in `git branch -r`; do git checkout $(echo $remote | cut -d'/' -f 2); done

Es ist wichtig zu beachten, dass Sie beim Abrufen, bei dem neue Remote-Tracking-Zweige heruntergefahren werden, nicht automatisch über lokale, bearbeitbare Kopien davon verfügen.

Jason Chen
quelle