Unterschied zwischen git checkout --track origin / branch und git checkout -b branch origin / branch

208

Kennt jemand den Unterschied zwischen diesen beiden Befehlen zum Umschalten und Verfolgen eines Remote-Zweigs?

git checkout -b branch origin/branch
git checkout --track origin/branch

Ich denke, beide verfolgen den Remote-Zweig, damit ich meine Änderungen am Ursprung auf den Zweig übertragen kann, oder?

Gibt es praktische Unterschiede?

Vielen Dank!

yorch
quelle

Antworten:

280

Die beiden Befehle haben den gleichen Effekt ( dank der Antwort von Robert Siemer für den Hinweis ).

Der praktische Unterschied ergibt sich aus der Verwendung eines lokalen Zweigs mit einem anderen Namen :

  • git checkout -b mybranch origin/abranchwird erstellen mybranchund verfolgenorigin/abranch
  • git checkout --track origin/abrancherstellt nur ' abranch', keinen Zweig mit einem anderen Namen.

(Das heißt, wie von Sebastian Graf kommentiert , wenn die lokale Niederlassung noch nicht existiert hätte.
Wenn dies der Fall wäre, müssten Sie git checkout -B abranch origin/abranch)


Hinweis: Mit Git 2.23 (Q3 2019) würde der neue Befehl verwendetgit switch :

git switch -c <branch> --track <remote>/<branch>

Wenn der Zweig in mehreren Fernbedienungen vorhanden ist und eine davon von der checkout.defaultRemoteKonfigurationsvariablen benannt wird, verwenden wir diese zum Zwecke der Begriffsklärung, auch wenn die <branch>nicht für alle Fernbedienungen eindeutig ist.
Setzen Sie es auf z. B., checkout.defaultRemote=originum entfernte Zweige von dort immer auszuchecken, wenn dies nicht <branch>eindeutig ist, aber auf der 'Ursprungs'-Fernbedienung vorhanden ist.

Hier -cist das Neue -b.


Zunächst einige Hintergrundinformationen: Tracking bedeutet, dass für einen lokalen Zweig der Upstream auf einen Remote-Zweig eingestellt ist:

# git config branch.<branch-name>.remote origin
# git config branch.<branch-name>.merge refs/heads/branch

git checkout -b branch origin/branch werden:

  • Erstellen / Zurücksetzen branchauf den Punkt, auf den verwiesen wird origin/branch.
  • Erstellen Sie den Zweig branch(mit git branch) und verfolgen Sie den Remote-Tracking-Zweig origin/branch.

Wenn ein lokaler Zweig von einem Remote-Tracking-Zweig gestartet wird, richtet Git den Zweig (insbesondere die Einträge branch.<name>.remoteund die branch.<name>.mergeKonfigurationseinträge) so ein, dass er git pullordnungsgemäß aus dem Remote-Tracking-Zweig zusammengeführt wird.
Dieses Verhalten kann über das globale branch.autosetupmergeKonfigurationsflag geändert werden . Diese Einstellung kann durch die Verwendung des außer Kraft gesetzt werden --trackund --no-trackOptionen, und später mit git Zweig geändert --set-upstream-to.


Und git checkout --track origin/branchwird das Gleiche tun wie git branch --set-upstream-to):

 # or, since 1.7.0
 git branch --set-upstream upstream/branch branch
 # or, since 1.8.0 (October 2012)
 git branch --set-upstream-to upstream/branch branch
 # the short version remains the same:
 git branch -u upstream/branch branch

Es würde auch den Upstream für ' branch' setzen.

(Hinweis: git1.8.0 wird veraltet sein git branch --set-upstreamund durch Folgendes ersetztgit branch -u|--set-upstream-to : siehe git1.8.0-rc1-Ankündigung )


Wenn eine vorgelagerte Niederlassung für eine lokale Niederlassung registriert ist, gilt Folgendes:

  • Sagen Sie git, dass er die Beziehung zwischen den beiden Zweigen in git statusund zeigen sollgit branch -v .
  • Weist git pull ohne Argumente an, aus dem Upstream zu ziehen, wenn der neue Zweig ausgecheckt wird .

Weitere Informationen finden Sie unter " Wie machen Sie einen vorhandenen Git-Zweig zu einem Remote-Zweig? ".

VonC
quelle
1
@VonC Ich habe nach dem kleinen Detail gesucht, das Sie zufällig als zusätzliche Information erwähnt haben. In meinem Fall war ich neugierig, warum einige meiner Zweige es mir erlaubten git pull, während einige Zweige nach einem entfernten Zweig fragten, aus dem ich ziehen konnte. Es stellt sich heraus, dass git weitergeht und branch.<BNAME>.remote=originzur lokalen gitconfig hinzufügt, wenn Sie zum ersten Mal einen von Ihrem Peer erstellten Remote-Zweig auschecken. Womit Sie dann ausstellen können git pull. Wenn Sie jedoch derjenige sind, der den Zweig erstellt git checkout -b BNAME, weiß git das natürlich nicht. Sie sollten also die Fernbedienung angeben.
Batilc
@batilc "Es stellt sich heraus, dass Sie beim ersten Mal einen von Ihrem Peer erstellten Remote-Zweig auschecken"; Ja, wenn ich git-scm.com/docs/git-checkout lese , sehe ich: " If <branch>wird nicht gefunden, aber es gibt einen Tracking-Zweig in genau einer Fernbedienung (nennen Sie es <remote>) mit einem passenden Namen, der als äquivalent zu $ git checkout -b <branch> --track <remote>/<branch>"
VonC
@VonC Ich habe eine bessere Konfiguration dafür gefunden. Das Einrichten branch.autoSetupMergevon alwaysführt einfach das aus, worüber wir sprechen. Diese Einstellung ist standardmäßig aktiviert. Dies truebedeutet, dass die Nachverfolgung nur beim Auschecken eines Remote-Zweigs durchgeführt wird. truerichtet kein Tracking für lokal erstellte Zweige ein.
Batilc
@ Batilc Ich stimme zu. Ich neige dazu, nicht immer zu verwenden, da ich das Tracking lieber explizit festlegen möchte, aber in Ihrem Fall sollte dies die richtige Einstellung sein.
VonC
1
"git branch --set-upstream-to branch upstream / branch" ist nicht die richtige Syntax. es sollte sein: "git branch --set-upstream-to-upstream / branch branch"
maharvey67
33

Es gibt überhaupt keinen Unterschied!

1) git checkout -b branch origin/branch

Wenn nein --trackund nein vorhanden ist --no-track, --trackwird dies als Standard angenommen. Die Standardeinstellung kann mit der Einstellung geändert werden branch.autosetupmerge.

In der Tat verhält sich 1) wie git checkout -b branch --track origin/branch.

2) git checkout --track origin/branch

"Aus Bequemlichkeit", --trackohne zu -bimplizieren -bund das Argument zu -bwird als "Zweig" vermutet. Das Erraten wird von der Konfigurationsvariablen gesteuert remote.origin.fetch.

In der Tat verhält sich 2) wie git checkout -b branch --track origin/branch.

Wie Sie sehen können: kein Unterschied.

Aber es wird noch besser:

3) git checkout branch

ist auch äquivalent zu, git checkout -b branch --track origin/branchwenn "Zweig" noch nicht existiert, "Ursprung / Zweig" jedoch 1 .


Alle drei Befehle setzen den "Upstream" von "Branch" auf "Origin / Branch" (oder sie schlagen fehl).

Upstream wird als Bezugspunkt Argumentationslos verwendet git status, git push, git mergeund somit git pull(wenn so konfiguriert ist ( dies ist die Standardeinstellung oder fast der Standard)).

ZB git statussagt Ihnen, wie weit Sie vor oder vor dem Upstream sind, wenn einer konfiguriert ist.

git pushist so konfiguriert, dass der aktuelle Zweig seit Git 2.0 standardmäßig 2 nach oben verschoben wird.

1 ... und wenn "Ursprung" die einzige Fernbedienung mit "Zweig"
2 ist, erzwingt die Standardeinstellung (mit dem Namen "einfach") auch, dass beide Zweignamen gleich sind

Robert Siemer
quelle
5

Das Buch scheint darauf hinzudeuten, dass diese Befehle den gleichen Effekt haben:

Der einfache Fall ist das Beispiel, das Sie gerade gesehen haben und in dem git checkout -b [branch] [remotename] / [branch] ausgeführt wird. Wenn Sie Git Version 1.6.2 oder höher haben, können Sie auch die Kurzform --track verwenden:

$ git checkout --track origin/serverfix 
Branch serverfix set up to track remote branch serverfix from origin. 
Switched to a new branch 'serverfix' 

Um einen lokalen Zweig mit einem anderen Namen als den Remote-Zweig einzurichten, können Sie problemlos die erste Version mit einem anderen lokalen Zweignamen verwenden:

$ git checkout -b sf origin/serverfix

Dies ist besonders praktisch, wenn Ihre Bash- oder Oh-My-Zsh-Git-Vervollständigungen den origin/serverfixNamen für Sie ziehen können - fügen Sie einfach --track(oder -t) hinzu und Sie sind auf dem Weg.

Klopfen
quelle
-1

Mit diesem Befehl können Sie keinen neuen Zweig erstellen

git checkout --track origin/branch

Wenn Sie Änderungen haben, die nicht bereitgestellt werden.

Hier ist ein Beispiel:

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   src/App.js

no changes added to commit (use "git add" and/or "git commit -a")

// TRY TO CREATE:

$ git checkout --track origin/new-branch
fatal: 'origin/new-branch' is not a commit and a branch 'new-branch' cannot be created from it

Mit dem folgenden git checkout -bBefehl können Sie jedoch problemlos einen neuen Zweig mit nicht bereitgestellten Änderungen erstellen :

$ git checkout -b new-branch
Switched to a new branch 'new-branch'
M       src/App.js
Grün
quelle
Denken Sie daran, dass beide Befehle in den Fragen zum Verfolgen eines vorhandenen Remote-Zweigs ( origin/branch) dienen
yorch
@Green Der Test, den Sie machen, ist mit origin/new-branchstatt origin/branch. Ist dir das bewusst?
Robert Siemer