如何确定分支是否没有父提交

时间:2017-11-06 15:24:47

标签: git

我正在编写一些工具,需要知道当前的分支位置/提交是否没有父项。 (这可能最有可能是一个没有提交的新存储库,或故意孤立的分支。)我需要一种检查命令行输出/退出代码的方法,这样就可以在程序中完成并自动完成。

理想情况下,这只能使用git管道命令来完成,但如果没有简单的方法,我可以使用git porcelain命令。

我如何可靠而简洁地确定git分支是否是孤儿?

3 个答案:

答案 0 :(得分:2)

这里的根本问题是孤儿分支并不存在。

真的,情况确实如此。在没有提交的新存储库中,没有分支:

$ mkdir tt
$ cd tt
$ git init
Initialized empty Git repository in ...
$ git branch
$ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

No commits yet输出相对较新,在Git版本2.14中。)

字面上没有提交的分支不存在。这就是名称master未显示在git branch输出中的原因:即使我们在它上面,分支主文件也不存在。

发生的事情是Git已将所需的分支名称存储到HEAD

$ git symbolic-ref HEAD
refs/heads/master

但分支本身不存在:

$ git rev-parse HEAD
HEAD
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

同样的事情在任何git checkout --orphan命令之后立即发生:符号引用HEAD确实存在,但它指向没有提交,因此git rev-parse HEAD失败。

在脚本中,使用git rev-parse -q --verify HEAD检查此状态。由于HEAD 总是作为名称存在, 1 当且仅当它包含不存在的分支的名称时才会解析。 修改:或者,如jthill notes in a comment,请使用git cat-file -e HEAD。如果HEAD有效,则rev-parse命令将打印当前提交的哈希ID,因此必须将其重定向到某处。如果HEAD有效,则两个命令都退出0,否则返回非零值。

现在,还有另一个不同的案例,Ôrel has already mentioned,当两个分支确实存在但不以任何方式相关时发生:

A--B--C   <-- master

D--E--F   <-- independent

这是一个存储库的示例,其中包含六个总提交(此处标记为AF,而不是使用真实的哈希ID)和两个分支名称。这两个分支都不与另一个分支相关,因此masterindepedent没有任何共同的提交,无论你从分支尖端遍历历史的距离多远。

测试两个分支是否不相关的最简单方法是使用git merge-base。两个分支尖端的合并基础是“最接近”尖端但是在每个尖端的祖先链中的提交。在图表中,它们是最低共同祖先节点。通常只有一个这样的节点,但在纵横交错的情况下可能有两个,而在不相关的分支的情况下,没有。

如果git merge-base表示没有,则两个分支无关。

1 如果删除HEAD文件,Git拒绝相信存储库存储库。如果您遇到内核崩溃/系统崩溃,可能会发生这种情况,因为文件HEAD往往非常活跃,可能会被崩溃后文件系统清理删除。如果确实发生了这种情况,将ref: refs/heads/master写入.git/HEAD可以为您保存所有内容。 : - )

答案 1 :(得分:1)

使用--is-ancestor

git merge-base --is-ancestor <maybe-ancestor-commit> <descendant-commit>

来自文档

  

- 是-祖先

     

检查第一个是否是第二个的祖先,并退出状态   如果为真则为0,否则为状态1。错误由非零表示   状态不是1.

您可以从初始提交

进行测试

获取初始提交

git rev-list --max-parents=0 HEAD

您的脚本可以是

git merge-base --is-ancestor `git rev-list --max-parents=0 HEAD`  TheBranchToTest

答案 2 :(得分:0)

当git链提交哈希时,如果没有与分支名称相关联的#,那么它表示它的孤立分支&amp;没有与他人联系

获取您所在的当前分行的名称:

git branch | grep "^*" | awk '{print $2}'

详细模式运行git branch&amp;只是寻找是否有哈希!

git branch -v | grep `git branch | grep "^*" | awk '{print $2}'`

我们可以根据需要在此基础上编写更多解析