2010-08-08 54 views
1

我正在写一个脚本,做一些微小的更改,然后将它们提交给git。因为这些都是微不足道的变化,所以只要我能够避开它,我就会想要做git commit --amend--具体来说,当修改不会“弄乱”任何其他分支机构的历史时。如果一个修改会搞乱另一个分支,我想要做一个标准的git commit如何检测git提交是否是其他提交的父代?

例如,如果我的树枝看上去像这样(一拉“可视化的所有分支历史” Git中GUI):

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

,我在主分支运行此脚本,然后我不我不想做一个修改,因为我会取代实验分支的一部分历史。从技术上讲,这并不会破坏任何东西 - 最初的提交仍然是实验历史的一部分,并且仍然会被引用,因此它不会被垃圾回收 - 但几乎不完全相同的提交两个不同的分支会让我后来想要重新组合或合并时遇到困难,所以这是我想避免的情况。

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

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

这个脚本是在Ruby中的,所以我可以通过shell来执行git命令行,或者我可以使用Ruby绑定来执行git - 无论哪种方式都可以让这个任务变得更容易。

回答

11

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

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

+0

您的第一个建议看起来非常适合我需要的东西。看起来我甚至可以做'git tag --contains HEAD'来为标签做同样的事情。 – 2010-08-08 18:19:46

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...

相关问题