我正在编写一些工具,需要知道当前的分支位置/提交是否没有父项。 (这可能最有可能是一个没有提交的新存储库,或故意孤立的分支。)我需要一种检查命令行输出/退出代码的方法,这样就可以在程序中完成并自动完成。
理想情况下,这只能使用git管道命令来完成,但如果没有简单的方法,我可以使用git porcelain命令。
我如何可靠而简洁地确定git分支是否是孤儿?
答案 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
这是一个存储库的示例,其中包含六个总提交(此处标记为A
到F
,而不是使用真实的哈希ID)和两个分支名称。这两个分支都不与另一个分支相关,因此master
和indepedent
没有任何共同的提交,无论你从分支尖端遍历历史的距离多远。
测试两个分支是否不相关的最简单方法是使用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}'`
我们可以根据需要在此基础上编写更多解析