问题
Are the following commands equivalent? If not, what are the differences?
git checkout -B a_branch
and
git branch -f a_branch HEAD
git symbolic-ref HEAD refs/heads/a_branch
See also this related post.
回答1:
Yes, they are extremely close, so much so that they might as well be identical.
You can stop here, the rest is because the above is a special case
They become much less close if you change one of them slightly. Consider that you can use this as:
git checkout -B name commit-specifier
as well as just:
git checkout -B name
which effectively means:
git checkout -B name HEAD
As the documentation says, the -b
and -B
flags are the "transactional equivalent" of some alternative sequence of commands. If those commands would (or do) fail somewhere along the way, the -b
or -B
action is suppressed. And git checkout commit-specifier
can in fact fail, when you have uncommitted changes that would be overwritten by checkout.
However, git checkout HEAD
should never fail. Given that it won't actually fail, the transactional nature of the -B
operation becomes unimportant. So now we look at what the documentation says this is the transactional-equivalent-of:
$ git branch -f <branch> [<start point>] $ git checkout <branch>
We know that the start-point is HEAD
, so:
git branch -f a_branch HEAD
is correct: this matches the first command. And, we know that git checkout <the commit we are already on>
is essentially a no-op (does not change the index and work-tree) and git checkout a_branch
ends up doing:
git symbolic-ref HEAD refs/heads/a_branch
as its final operation, so:
git checkout -B a_branch
"means":
- don't do anything to the index and work-tree (which succeeds);
- if that succeeds (which it does), reset
a_branch
to the current commit; and - if that succeeds (which it does), make
HEAD
refer toa_branch
.
If we add the starting point, though, step 1 may fail, and step 2, if run, does something different.
来源:https://stackoverflow.com/questions/43374766/checkout-b-vs-symbolic-ref