git checkout——track origin/branch和git checkout -b branch origin/branch的区别

有人知道这两个切换和跟踪远程分支的命令之间的区别吗?

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

我想两者都在跟踪远程分支所以我可以在原点上把我的更改推到分支,对吧?

有什么实际的区别吗?

218113 次浏览

这两个命令具有相同的效果(感谢Robert Siemer的回答,他指出了这一点)。

实际的区别出现在使用名为不同的的本地分支时:

  • git checkout -b mybranch origin/abranch将创建mybranch并跟踪origin/abranch
  • git checkout --track origin/abranch将只创建'abranch',而不是具有不同名称的分支。

(也就是说,正如评论 by 塞巴斯蒂安·格拉夫,如果本地分支已经存在 如果是,你需要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>是模棱两可的,但存在于'origin'远程上,则总是从那里签出远程分支

这里,'-c'是新的'-b'。


首先,一些背景知识:跟踪意味着本地分支的上游被设置为远程分支:

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

git checkout -b branch origin/branch将:

  • 创建/重置branchorigin/branch引用的点。
  • 创建分支branch(使用git branch)并跟踪远程跟踪分支origin/branch

当一个本地分支从一个远程跟踪分支启动时,Git会设置这个分支(特别是__ABC0和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 显示__ABC0和git branch -v中两个分支之间的关系
  • 指导git pull 不带参数当新分支签出时从上游提取

更多信息见“如何让现有的git分支跟踪远程分支?”。

这本书似乎表明这些命令产生相同的效果:

简单的例子就是你刚刚看到的,运行git checkout -b (分支)[remotename] /[分支]。如果你的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 -b branch origin/branch

如果没有--track--no-track,则假定--track为默认值。可以通过设置branch.autosetupmerge来更改默认值。

实际上,1)行为类似git checkout -b branch --track origin/branch

2) git checkout --track origin/branch

"为了方便起见",没有-b--track暗示-b,并且-b的实参被猜测为" branch "。猜测是由配置变量remote.origin.fetch驱动的。

实际上,2)行为类似git checkout -b branch --track origin/branch

正如你所看到的:没有区别。

但还有更好的:

3) git checkout branch

如果" branch "还不存在,而" origin/branch "存在__abc1,则它也等价于git checkout -b branch --track origin/branch


这三个命令都将“branch”的“upstream”设置为“origin/branch”(否则会失败)。

Upstream被用作无参数git statusgit pushgit mergegit pull的参考点(如果这样配置(这是默认的或几乎是默认的))。

例如,git status告诉你你落后或领先上游多远,如果配置了一个。

自git 2.0以来,git push被配置为通过default2将当前分支推入上游。

< p > <一口> 1……如果“origin”是唯一具有“branch”
的远程 2默认值(命名为" simple ") 强制两个分支名称相等

你不能用这个命令创建一个新的分支

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