`checkout -B` 与 `symbolic-ref`

`checkout -B` vs. `symbolic-ref`

以下命令是否等效?如果不是,有什么区别?

git checkout -B a_branch

git branch -f a_branch HEAD
git symbolic-ref HEAD refs/heads/a_branch


另见

是的,它们非常接近,以至于它们可能完全相同。

到此为止,剩下的就是因为以上是特例

如果你稍微改变其中之一,它们就会变得不那么接近。考虑一下您可以将其用作:

git checkout -B <em>name</em> <em>commit-specifier</em>

以及:

git checkout -B <em>name</em>

这实际上意味着:

git checkout -B <em>name</em> HEAD

正如 the documentation 所说,-b-B 标志是一些替代命令序列的 "transactional equivalent"。如果这些命令将(或确实)在某个地方失败,-b-B 操作将被 抑制 git checkout <em>commit-specifier</em> 实际上可能会失败,当您有未提交的更改将被 checkout 覆盖时。

但是,git checkout HEAD应该永远不会失败。鉴于它实际上不会失败,-B 操作的事务性质变得不重要。所以现在我们看看文档说这是什么交易等价物:

$ git branch -f <branch> [<start point>]
$ git checkout <branch>

我们知道起点是HEAD,所以:

git branch -f a_branch HEAD

是正确的:这与第一个命令匹配。而且,我们知道 git checkout <the commit we are already on> 本质上是一个空操作(不更改索引和工作树)并且 git checkout a_branch 最终会做:

git symbolic-ref HEAD refs/heads/a_branch

作为它的最终操作,所以:

git checkout -B a_branch

"means":

  1. 不要对索引和工作树做任何事情(成功);
  2. 如果成功(确实如此),将 a_branch 重置为当前提交;和
  3. 如果成功(确实如此),使 HEAD 引用 a_branch

但是,如果我们添加起点,则第 1 步可能 失败 ,而第 2 步 运行 可能会有所不同。