Różnica między git checkout --track origin / branch i git checkout -b branch origin / branch

208

Czy ktoś zna różnicę między tymi dwoma poleceniami przełączania i śledzenia zdalnej gałęzi?

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

Wydaje mi się, że oboje śledzą gałąź zdalną, więc mogę przesłać moje zmiany do gałęzi na początku, prawda?

Czy są jakieś praktyczne różnice?

Dzięki!

jorch
źródło

Odpowiedzi:

281

Oba polecenia mają ten sam efekt ( dzięki odpowiedzi Roberta Siemera za wskazanie go ).

Praktyczna różnica wynika z używania oddziału lokalnego o innej nazwie :

  • git checkout -b mybranch origin/abranchutworzy mybranchi będzie śledzićorigin/abranch
  • git checkout --track origin/abranchutworzy tylko „ abranch”, a nie gałąź o innej nazwie.

(To znaczy, jak skomentował przez Sebastiana Graf , jeśli lokalny oddział czy nie istnieje.
Jeśli tak, to trzeba git checkout -B abranch origin/abranch)


Uwaga: w przypadku Git 2.23 (III kwartał 2019 r.) Można by użyć nowego poleceniagit switch :

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

Jeśli gałąź istnieje w wielu pilotach, a jeden z nich jest nazwany przez checkout.defaultRemotezmienną konfiguracyjną, użyjemy tego do celów ujednoznacznienia, nawet jeśli <branch>nie jest on unikalny dla wszystkich pilotów.
Ustaw na np., checkout.defaultRemote=originAby zawsze kasował zdalne gałęzie stamtąd, jeśli <branch>jest niejednoznaczny, ale istnieje na zdalnym źródle.

Tutaj -c„jest nowy -b”.


Po pierwsze, pewne tło: Śledzenie oznacza, że ​​gałąź lokalna ma swój górny segment ustawiony na gałąź zdalną:

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

git checkout -b branch origin/branch będzie:

  • utwórz / zresetuj branchdo punktu, do którego odnosi się origin/branch.
  • utwórz gałąź branch(za pomocą git branch) i śledź gałąź zdalnego śledzenia origin/branch.

Kiedy gałąź lokalna jest uruchamiana z gałęzi zdalnego śledzenia, Git konfiguruje gałąź (szczególnie wpisy branch.<name>.remotei branch.<name>.mergekonfiguracyjne), aby git pullodpowiednio połączyć się z gałęzią zdalnego śledzenia.
To zachowanie można zmienić za pomocą branch.autosetupmergeflagi konfiguracji globalnej . Że ustawienie może być zmienione za pomocą przycisków --tracki --no-trackopcji, a później zmienić za pomocą git oddział --set-upstream-to.


I git checkout --track origin/branchzrobi to samo co 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

Ustawiłoby to również upstream dla „branch ”.

(Uwaga: git1.8.0 przestanie obowiązywać git branch --set-upstreami zastąpi go git branch -u|--set-upstream-to: zobacz komunikat git1.8.0-rc1 )


Po zarejestrowaniu oddziału wyższego szczebla dla oddziału lokalnego:

  • powiedz git, aby pokazał związek między dwiema gałęziami w git statusigit branch -v .
  • kieruje git pull bez argumentów, aby pobierać z góry, gdy nowy oddział jest wyewidencjonowany .

Zobacz „ Jak sprawić, aby istniejąca gałąź git śledziła gałąź zdalną? ”, Aby uzyskać więcej.

VonC
źródło
1
@VonC Szukałem tego małego szczegółu, o którym wspomniałeś jako dodatkowej informacji. W moim przypadku byłem ciekawy, dlaczego niektóre gałęzie mi na to pozwalają git pull, podczas gdy niektóre prosiłyby o wyciągnięcie zdalnej gałęzi. Okazuje się, że jeśli po raz pierwszy sprawdzasz zdalną gałąź, którą utworzył twój rówieśnik, git kontynuuje i dodaje branch.<BNAME>.remote=origindo lokalnego gitconfig. Który następnie pozwala na wydanie git pull. Jednak jeśli to ty tworzysz gałąź git checkout -b BNAME, git - oczywiście - nie wie. Więc powinieneś określić jego zdalny.
batilc
@batilc "Okazuje się, że jeśli po raz pierwszy sprawdzasz zdalną gałąź utworzoną przez twojego partnera,"; tak, czytając git-scm.com/docs/git-checkout , widzę: „ If <branch>nie znaleziono, ale istnieje dokładnie gałąź śledzenia w jednym pilocie (nazwij ją <remote>) o pasującej nazwie, traktuj jako odpowiednik $ git checkout -b <branch> --track <remote>/<branch>
VonC
@VonC Znalazłem lepszą konfigurację do tego. konfigurowania branch.autoSetupMergeaby alwayspo prostu preform, co mówimy o. Domyślnie jest to ustawienie true, co oznacza, że ​​śledzenie będzie wykonywane tylko podczas sprawdzania zdalnej gałęzi. truenie konfiguruje śledzenia lokalnie utworzonych oddziałów.
batilc
@batilc Zgadzam się. Nie zawsze używam, ponieważ wolę jawnie ustawić śledzenie, ale w twoim przypadku powinno to być właściwe ustawienie.
VonC
1
„git branch --set-upstream-to branch upstream / branch” nie jest poprawną składnią. powinno to być: „Git Branch --set-upstream-to upstream / Branch Branch”
maharvey67 10.10.2018
33

Nie ma żadnej różnicy!

1) git checkout -b branch origin/branch

Jeśli nie ma --tracki nie --no-track, --trackprzyjmuje się , że jest domyślna. Ustawienie domyślne można zmienić za pomocą ustawienia branch.autosetupmerge.

W efekcie 1) zachowuje się jak git checkout -b branch --track origin/branch.

2) git checkout --track origin/branch

„Dla wygody” --trackbez -bimplikacji, -ba argumentem -bdomniemanym jest „gałąź”. Zgadywanie jest zależne od zmiennej konfiguracyjnej remote.origin.fetch.

W efekcie 2) zachowuje się jak git checkout -b branch --track origin/branch.

Jak widać: bez różnicy.

Ale robi się jeszcze lepiej:

3) git checkout branch

jest również równoważne, git checkout -b branch --track origin/branchjeśli „gałąź” jeszcze nie istnieje, ale „pochodzenie / gałąź” ma wartość 1 .


Wszystkie trzy polecenia ustawiają „upstream” „branch” na „origin / branch” (lub zawodzą).

Górę jest używany jako punkt odniesienia argumentu mniej git status, git push, git mergea zatemgit pull (jeśli jest skonfigurowana tak (który jest domyślnym lub prawie domyślny)).

Np. git statusMówi ci, jak daleko jesteś lub do przodu, jeśli jesteś skonfigurowany.

git pushjest skonfigurowany do wypychania bieżącej gałęzi w górę 2 domyślnie od git 2.0.

1 ... a jeśli „origin” jest jedynym pilotem mającym „gałąź”
2, domyślna nazwa („prosta”) wymusza również równość obu nazw gałęzi

Robert Siemer
źródło
5

Książka wydaje się wskazywać, że te polecenia dają taki sam efekt:

Prostym przypadkiem jest przykład, który właśnie widziałeś, uruchamiając git checkout -b [gałąź] [nazwa zdalna] / [gałąź]. Jeśli masz Git w wersji 1.6.2 lub nowszej, możesz także użyć skrótu --track:

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

Aby skonfigurować oddział lokalny o innej nazwie niż oddział zdalny, możesz łatwo użyć pierwszej wersji z inną nazwą oddziału lokalnego:

$ git checkout -b sf origin/serverfix

Jest to szczególnie przydatne, gdy twoje kompilacje bash lub oh-my-zsh git są w stanie wyciągnąć origin/serverfixnazwę dla ciebie - wystarczy dołączyć --track(lub -t) i jesteś na dobrej drodze.

Poklepać
źródło
-1

Za pomocą tego polecenia nie można utworzyć nowego oddziału

git checkout --track origin/branch

jeśli masz zmiany, które nie są wprowadzane.

Oto przykład:

$ 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

Możesz jednak łatwo utworzyć nowy oddział z nieetapowymi zmianami za pomocą git checkout -bpolecenia:

$ git checkout -b new-branch
Switched to a new branch 'new-branch'
M       src/App.js
Zielony
źródło
pamiętaj, że oba polecenia w pytaniach służą do śledzenia istniejącej zdalnej gałęzi ( origin/branch)
rok
@Green Test, który wykonujesz, to origin/new-branchzamiast origin/branch. Czy jesteś tego świadomy?
Robert Siemer