什么`git checkout ...`做什么?

Chr*_*son 54 git

我偶尔会不小心写git checkout ...,这让我处于一个独立的头状态.我想知道为什么.这是"点故事":

> git checkout .
# checks out current directory
> git checkout ..
# Checks out parent directory, if in repository.
> git checkout ...
# Puts into detached head state?
> git checkout ....
error: pathspec '....' did not match any file(s) known to git.
Run Code Online (Sandbox Code Playgroud)

lar*_*sks 48

这是此语法的简并形式,在gitrevisions(7)手册页中进行了描述:

   <rev1>...<rev2>
       Include commits that are reachable from either <rev1> or <rev2> but
       exclude those that are reachable from both. When either <rev1> or
       <rev2> is omitted, it defaults to HEAD.
Run Code Online (Sandbox Code Playgroud)

注意最后一位,"当省略<rev1><rev2>省略时,它默认为HEAD".这意味着写作...相当于HEAD...HEAD.在git checkout此使用时,最终会评估HEAD的提交ID.也就是说,你只是在做:

git checkout HEAD^{commit}
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的,但也有一些微妙之处:Git在名为`get_oid_mb`的函数中实现了这一点,其中`mb`代表Merge Base.它确实检查了三个点`...'表示法,当它出现时,解析两边的两个转速(或者如前所述使用`HEAD`)然后,实际上,运行`git merge-base --all < rev1> <rev2>`获取合并基础.如果只有一个这样的合并库,那就是提交; 否则```无法解决. (6认同)
  • (顺便说一下,当我说"所有其他"时,我的意思是"除了`git checkout`和`git diff`之外的所有内容.`git diff`中的代码使用你看到的内部版本,如果你运行`git rev-parse`:试试例如,运行一个文字`git rev-parse ...`.但是`git diff`然后以一种当前稍微破碎的方式转换正参考集和负参考集,如果有一个合并基础那么效果很好.) (3认同)
  • `git diff`命令用于使用相同的技巧:`git diff A ... B`表示`git diff $(git merge-base AB)B`,我想也许代码是共享的.现在`git checkout`是`get_oid_mb`的唯一用户.所有其他情况都按照文档中的描述对待它,即实际上不运行`git merge-base --all`. (2认同)