Різниця між git checkout - трек походження / гілка та git checkout -b походження філії / гілка


208

Хтось знає різницю між цими двома командами для перемикання та відстеження віддаленої гілки?

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

Я думаю, що обидва слідкують за віддаленою гілкою, щоб я міг підштовхнути свої зміни до гілки за походженням, правда?

Чи є якісь практичні відмінності ??

Дякую!

Відповіді:


281

Дві команди мають однаковий ефект ( завдяки відповіді Роберта Сімера за його вказівку ).

Практична різниця виникає при використанні локальної гілки, названої інакше :

  • git checkout -b mybranch origin/abranchстворить mybranchі відстежитьorigin/abranch
  • git checkout --track origin/abranchстворить лише " abranch", а не гілку з іншою назвою.

(Тобто, за зауваженням від Себастьяна Graf , якщо місцеве відділення було НЕ існує вже.
Якщо це так, вам потрібно буде git checkout -B abranch origin/abranch)


Примітка: з Git 2.23 (Q3 2019), що використовує нову командуgit switch :

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

Якщо гілка існує в декількох віддалених мережах, і одна з них названа checkout.defaultRemoteзмінною конфігурації, ми будемо використовувати цю для цілей розбірливості, навіть якщо <branch>вона не є унікальною для всіх видалень.
Встановіть його, наприклад, checkout.defaultRemote=originзавжди перевіряти віддалені гілки звідти, якщо <branch>це неоднозначно, але існує на віддаленому "поколінні".

Тут ' -c' є новим ' -b'.


По-перше, деякий передумови: відстеження означає, що локальна гілка встановлена ​​на віддаленій гілці:

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

git checkout -b branch origin/branch буде:

  • створити / скинути branchдо точки, на яку посилається origin/branch.
  • створити гілку branchgit branch) і відстежити гілку відстеження origin/branch.

Коли локальна гілка запускається з гілки віддаленого відстеження, Git встановлює гілку (зокрема, записи branch.<name>.remoteта branch.<name>.mergeконфігурацію), щоб git pullвідповідним чином зливатися з гілкою віддаленого відстеження.
Ця поведінка може бути змінена через глобальний branch.autosetupmergeпрапор конфігурації. Цей параметр може бути подолана з допомогою --trackі --no-trackопцій, а також змінити пізніше з допомогою Git філії --set-upstream-to.


І git checkout --track origin/branchзробимо так само, як 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

Це також встановило б вище " branch".

(Примітка: git1.8.0 буде застарілим git branch --set-upstreamі замінить його на git branch -u|--set-upstream-to: див. Повідомлення git1.8.0-rc1 )


Зареєстрована філія для місцевого відділення:

  • скажіть git, щоб показати зв’язок між двома гілками в git statusіgit branch -v .
  • направляє git pull без аргументів тягнути з висхідного потоку, коли перевіряється нова гілка .

Див. " Як створити існуючу гіт-гілку для віддаленої гілки? "


1
@VonC Я шукав цю маленьку деталь, яку ти випадково зазначив як додаткову інформацію. У моєму випадку мені було цікаво, чому я маю деякі мої гілки, що дозволяють мені git pull, тоді як деякі гілки просять витягнутий відділення. Виявляється, якщо ви вперше перевіряєте віддалену гілку, яку створив ваш одноліток, git продовжується і додає branch.<BNAME>.remote=originдо локальної gitconfig. Що потім дозволяє оформити git pull. Однак, якщо ви створюєте гілку git checkout -b BNAME, то git - звичайно, не знає. Тому слід вказати його пульт.
batilc

@batilc "Виявляється, якщо ви вперше перевіряєте віддалену гілку, яку створив ваш одноліток"; так, читаючи git-scm.com/docs/git-checkout , я бачу: " If <branch>не знайдено, але існує гілка відстеження точно в одному віддаленому (назвіть його <remote>) з відповідним ім'ям, $ git checkout -b <branch> --track <remote>/<branch>
трактуйте

@VonC Я знайшов кращу конфігурацію для цього. настройка branch.autoSetupMergeдля alwaysпросто виконує те , що ми говоримо. Це налаштування за замовчуванням true, що означає, що відстеження буде виконуватися лише під час перевірки віддаленої гілки. trueне налаштовує відстеження для локально створених гілок.
batilc

@batilc Я згоден. Я схильний використовувати не завжди, так як я віддаю перевагу явно встановити відстеження, але у вашому випадку це має бути правильне налаштування.
VonC

1
"гілка гіти --set-upstream-to гілка вгору / гілка" не є правильним синтаксисом. це повинно бути: "git branch --set-upstream-to upstream / branch branch"
maharvey67

33

Різниці немає взагалі!

1) git checkout -b branch origin/branch

Якщо немає --trackі немає --no-track, --trackвважається за замовчуванням. За замовчуванням можна змінити налаштування branch.autosetupmerge.

Насправді 1) поводиться так git checkout -b branch --track origin/branch.

2) git checkout --track origin/branch

"Як зручність", --trackбез будь-яких -bприпущень -bі аргументів, як -bвважається, "галузь". Відгадування керується змінною конфігурації remote.origin.fetch.

Насправді 2) поводиться так git checkout -b branch --track origin/branch.

Як бачите: різниці немає.

Але стає ще краще:

3) git checkout branch

також еквівалентно, git checkout -b branch --track origin/branchякщо "гілка" ще не існує, але "походження / гілка" робить 1 .


Усі три команди встановлюють, що "вище" за "гілкою" є "початком / гілкою" (або вони не відповідають).

Вгору по течії використовується в якості опорної точки аргумент менш git status, git push, git mergeі , таким чином , git pull(якщо він налаштований таким чином (який за замовчуванням або майже за замовчуванням)).

Напр., git statusВам повідомляється, як далеко ви позаду або вперед, якщо ви налаштовані.

git pushза замовчуванням налаштовано для виштовхування поточної гілки за течією 2, оскільки git 2.0.

1 ... і якщо "походження" є єдиним віддаленим, що має "відділення"
2, за замовчуванням (названим "простим") також примушує обидві назви гілок бути рівними


5

Здається, книга вказує на те, що ці команди дають той же ефект:

Простий випадок - приклад, який ви щойно побачили, запускаючи git checkout -b [гілка] [віддалене ім'я] / [гілка]. Якщо у вас є версія Git 1.6.2 або пізнішої версії, ви також можете скористатися скороченням --track:

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

Щоб налаштувати локальну гілку з іншою назвою, ніж віддалена гілка, ви можете легко використовувати першу версію з іншою назвою місцевої гілки:

$ git checkout -b sf origin/serverfix

Це особливо зручно, коли ваші завершення bash або oh-my-zsh git здатні витягнути origin/serverfixназву для вас - просто додайте --track(або -t) і ви вже на шляху.


-1

Ви не можете створити нову гілку за допомогою цієї команди

git checkout --track origin/branch

якщо у вас є зміни, які не ставлять поетапно.

Ось приклад:

$ 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

Однак ви можете легко створити нову гілку за допомогою поетапних змін за допомогою git checkout -bкоманди:

$ git checkout -b new-branch
Switched to a new branch 'new-branch'
M       src/App.js

майте на увазі, що обидві команди в питаннях для відстеження наявної віддаленої гілки ( origin/branch)
yorch

@Green Тест, який ви робите, origin/new-branchзамість нього origin/branch. Вам це відомо?
Роберт Сімер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.