1

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

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

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

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

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

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

这个脚本是用 Ruby 编写的,所以我可以使用 git 命令行,或者我可以为 git 使用 Ruby 绑定——无论哪种方式都可以使这项任务更容易。

4

2 回答 2

12

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

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

于 2010-08-08T17:46:43.710 回答
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

在上面的例子中,commit6910...有一个孩子,ef8a....

于 2010-08-08T16:23:45.970 回答