Разница между git checkout --track origin / branch и git checkout -b branch origin / branch

209

Кто-нибудь знает разницу между этими двумя командами для переключения и отслеживания удаленной ветви?

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

Я думаю, что оба отслеживают удаленную ветвь, поэтому я могу перенести свои изменения в ветку в начале, верно?

Есть ли практические отличия ??

Спасибо!

yorch
источник

Ответы:

282

Эти две команды имеют одинаковый эффект ( спасибо ответу Роберта Симера за указание на это ).

Практическая разница возникает при использовании локальной ветки с другим именем :

  • 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 без аргументов для извлечения из восходящего потока при извлечении новой ветви .

Смотрите " Как сделать так, чтобы существующая ветка git отслеживала удаленную ветку? "

VonC
источник
1
@VonC Я искал ту маленькую деталь, которую ты упомянул в качестве дополнительной информации. В моем случае мне было любопытно, почему мне позволили некоторые мои ветви git pull, тогда как некоторые ветви попросили бы удалить удаленную ветку. Оказывается, если вы впервые проверяете удаленную ветку, которую создал ваш пир, git branch.<BNAME>.remote=originзапускается и добавляет локальный gitconfig. Который затем позволяет выпускать git pull. Однако, если вы тот, кто создает ветку git checkout -b BNAME, то git, конечно, не знает. Поэтому вы должны указать его удаленный.
батик
@batilc "Оказывается, если вы в первый раз проверяете удаленную ветку, которую создал ваш пир",; да, читая git-scm.com/docs/git-checkout , я вижу: « If <branch>не найден, но существует ветвь отслеживания ровно в одном удаленном (вызовите его <remote>) с совпадающим именем, рассматривайте как эквивалентное $ git checkout -b <branch> --track <remote>/<branch>»
VonC
@VonC Я нашел лучшую конфигурацию для этого. настройка branch.autoSetupMergeдля alwaysпросто выполняет то , что мы говорим. Этот параметр по умолчанию trueравен, что означает, что отслеживание будет выполняться только при извлечении удаленной ветви. trueне настраивает отслеживание для локально созданных филиалов.
батил
@batilc Я согласен. Я склонен не использовать всегда, так как я предпочитаю явно устанавливать отслеживание, но в вашем случае это должно быть правильное значение.
VonC
1
«git branch --set-upstream-to branch upstream / branch» неверный синтаксис. это должно быть: "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 ... и если «origin» является единственным удаленным устройством, имеющим «ответвление»
2, то по умолчанию (называемое «simple») также обеспечивает одинаковое имя обеих ветвей

Роберт Симер
источник
5

Книга, кажется, указывает, что эти команды дают тот же эффект:

Простой случай - это пример, который вы только что видели, запустив git checkout -b [branch] [remotename] / [branch]. Если у вас 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. Вы знаете об этом?
Роберт Симер