如何检测git commit是否是其他提交的父级?

时间:2010-08-08 16:06:12

标签: ruby git amend

我正在编写一个脚本,进行一些微不足道的更改,然后将它们提交给git。因为这些都是微不足道的变化,所以每当我能够逃脱它时,我想做git commit --amend - 特别是当修正不会“弄乱”任何其他分支的历史时。如果修改会弄乱另一个分支,我想改为标准git commit

例如,如果我的分支看起来像这样(在Git GUI中“可视化所有分支历史记录”):

* [experimental branch] Added feature.
* [master branch] Trivial change from script
* ...

我正在主分支上运行这个脚本,然后我不想修改,因为我将替换实验分支的历史部分。从技术上讲,这实际上不会破坏任何东西 - 原始提交仍然是实验历史的一部分,并且仍将被引用,因此它不会被垃圾收集 - 但是在几乎但不完全相同的提交中当我后来想要改变或合并时,两个不同的分支会让生活变得困难,所以这是我想要避免的情况。

如何让我的脚本自动检测提交是否有任何分支?

如果简化假设有帮助,我总是在master的头上运行这个脚本,我只使用git作为本地存储库 - 我不会在任何地方推送或拉动更改。

这个脚本是在Ruby中的,所以我可以使用git命令行,或者我可以使用Ruby绑定git - 无论哪个都可以使这个任务更容易。

2 个答案:

答案 0 :(得分:12)

只需运行git branch --contains HEAD即可获得“包含”此提交的分支列表。如果列表为空,则该提交应该是安全的以进行修改。您还可能希望包含-a标志以列出本地AND远程分支。

或者,您可以将git rev-parse HEAD的输出与git merge-base HEAD other-branch进行比较。如果这些提交ID相同,则当前提交位于其他分支的提交历史记录中。

答案 1 :(得分:3)

提交图是单向的:给定提交,你知道它的所有祖先,但不知道它的任何子节点。你必须从端点开始并回溯,直到你得到你想要的提交。

使用git rev-list [some commit] --children(HEAD是默认设置):

$ git rev-list HEAD --children
6edbee61c87fb063700751815f0ad53907d0b7a4
aee452860ecd772b8bdcd27227e6a72e6f4435fd 6edbee61c87fb063700751815f0ad53907d0b7a4
ef8a1487b03256a489d135e76d1f0b01872f2349 aee452860ecd772b8bdcd27227e6a72e6f4435fd
6910dc5833f6cd26133e32bef40ed54cf9337017 ef8a1487b03256a489d135e76d1f0b01872f2349
bbef0da56efe048f70293bd20bad0cb37b5e84f0 6910dc5833f6cd26133e32bef40ed54cf9337017
[...]

左侧列是反向时间顺序的提交SHA-1列表。该提交的任何内容都是该提交的子(--children)。最高提交是HEAD,因此没有孩子。

因此,如果你在这个列表中grep你的SHA-1并且它有任何东西,它至少有一个孩子:

$ git rev-list --children | grep '^6910'
6910dc5833f6cd26133e32bef40ed54cf9337017 ef8a1487b03256a489d135e76d1f0b01872f2349

在上面的示例中,提交6910...有一个孩子ef8a...