从中央仓库创建本地分支的标准方式是什么?
假设中央回购有master
, branch_A
和branch_B
。 在我的本地工作空间中,我只有master
和branch_A
。
我想以一种干净的方式在我的工作空间中获得本地分支branch_B
。
即我想从中央回购的branch_B
获得相同的确切内容,而不是其他任何东西。
我认为git checkout -b my_name/branch_B
会执行此操作。 但是,当我这样做时,我遇到了很多冲突,我不知道为什么。
我不想手动解决冲突。 我想要的只是从中央branch_B
的branch_B
获取相同的确切内容,而没有其他任何内容(即,如果有任何其他情况,则丢弃任何本地更改)
即使branch_B
不存在,你想要的只是git checkout branch_B
。 事实上,关键是它不存在,否则git checkout
不能创建它。
不过,在你使用之前,花点时间考虑一下:你根本不是“从中央回购中创建分支”。 你不能:你只能在你自己的仓库上操作。
这可能看起来没有区别,但是从Git奇怪的许多位中理解它是非常重要的。 你所做的一切,你对自己的存储库所做的或所做的一切。
(这是一种例外 - 但并非真正的 - 是git push
,在这里,你将自己已经做过的事情提交给自己的仓库,并将它们提供给另一个拥有自己仓库的Git,然后请求它根据你提供的内容对它的存储库进行操作,这取决于Git将它们做到自己的存储库中。)
集中存储库
在处理中央存储库时,从中获取资料的方式是使用git fetch
。 fetch
命令调用它们的Git并向它们请求它们的分支名称和其他这样的引用的列表,这给Git分支提示提交ID(SHA-1散列)。 您的Git然后通过哈希ID和任何其他需要完成提取所需的对象(文件,或技术上的“blob”,树形对象,早期提交以及它们的树和blob,以及注释标记对象)来请求任何提交对象。 然后,Git将所有这些对象都放在您的存储库中,并且作为最后一步,将其所有分支名称重命名为您的Git保证不会与任何分支名称冲突的新名称。
你的Git从他们的名字中合成的新名称是你的远程跟踪分支( origin/master
等)。 这些是通过git fetch
创建和更新的。 如果你使用--prune
,或者将默认设置为pruning,那么你的git fetch
操作会从你的仓库中删除任何远程追踪分支名称,这些分支名称在其他Git中不再有相应的常规分支。 (这有时是有用的,但不是默认的,可能出于历史原因加上“仅在其他回购中有很多分支创建和删除”方面有用)。
origin/master
的origin
部分就是远程的名称。 实际上,远程只是一个名称 - 通常origin
,因为这是由git clone
创建的默认值,您的Git将存储用于git fetch
的URL。 这些远程追踪分支的名称是通过将远程的名称放在远程分支名称的前面来构造的:因此, master
成为origin/master
, branch_A
成为origin/branch_A
,依此类推。
为什么git checkout
会创建分支
你想要的命令的长形式是:
git checkout -b branch_B --track origin/branch_B
(假设您的其他中央存储库已根据origin
归档)。 -b
这里的意思是“创建一个分支”,而--track
意味着:“我将提供另一个名称,我希望你,我的Git在我的存储库中查找以查找提交哈希ID。做到这一点,我也希望你做一个git branch --set-upstream-to
的git branch --set-upstream-to
branch。“ 最后,当然, origin/branch_B
是(已经存在的)远程跟踪分支的名称。
这会被大量使用,所以Git人员决定让git checkout
变得更聪明:如果你要求Git按名称签出分支,而且它不存在, git checkout
会查看是否有某个远程跟踪分支在从远程追踪分支名称剥离遥控器之后,使用相同的名称。 (Whew!)也就是说,如果你git checkout sneeze
,你的Git会查看是否有origin/sneeze
或者upstream/sneeze
或其他。
如果只有一个这样的远程跟踪分支,那么git checkout
会指示创建一个本地分支,并使用远程跟踪分支的当前哈希ID作为起点。
但捷径确实必须完全按此方式拼写
需要注意的是git checkout -b branch_B
不会使一个新的branch_B
从出发origin/branch_B
。 它只是从当前提交开始创建一个新的branch_B
。 新分公司也没有设立跟踪任何远程追踪分行。 这是因为-b
告诉git checkout
立即创建分支,所以它不会触发“嘿,等等,我没有现有的branch_B
...也许我应该运行一些自动特殊情况代码?” 码。
当然, origin/branch_B
特殊情况代码正常工作,您必须在存储库中有origin/branch_B
。 它不会伸出手并在集中式存储库上找到它。 只有git fetch
会这样做 - 这只是git fetch
和git push
,它们实际上会调用另一个Git,并使用隐藏在远程名称下的URL。
(事实上, git remote
有时也会调用另一个Git,但这是其他SO问题。)
您需要执行:
git checkout -b branch_B origin/branch_B
“origin”是远程存储库的默认名称。 要知道正确的名字execute:
git remote -v
首先git fetch
在git fetch
您的本地回购应该已经从中央回购库中获取所有分支,通常称为origin
。
这将创建一个名为origin/branch_B
的本地远程跟踪分支:
$ git fetch
* [new branch] branch_B -> origin/branch_B
这个远程追踪分支origin/branch_B
跟踪您的origin/branch_B
回购的最新变化。
你不应该承诺它,所以你需要创建一个实际的分支来处理。
然后git checkout branch_B
然后,简单的git checkout branch_B
应该创建一个本地的branch_B
来自动跟踪origin/branch_B
:
$ git checkout branch_B
Branch branch_B set up to track remote branch branch_B from origin.
Switched to a new branch 'branch_B'
如果你想列出你的本地和远程分支,你可以使用git branch -va
。
上一篇: What is the standard way to create a local branch from a central repo?