如何检测 git 提交是否是其他提交的父级?
我正在编写一个脚本,进行一些细微的更改,然后将它们提交到 git。因为这些都是微不足道的更改,所以只要我能逃脱惩罚,我就想执行 git commit --amend ,特别是当修改不会“搞乱”任何其他分支的历史记录时。如果修改会弄乱另一个分支,我想做一个标准的 git commit 来代替。
例如,如果我的分支看起来像这样(Git GUI 中的“可视化所有分支历史记录”):
* [experimental branch] Added feature.
* [master branch] Trivial change from script
* ...
并且我在主分支上运行此脚本,那么我不想进行修改,因为我会替换实验分支的部分历史。从技术上讲,这实际上不会破坏任何东西——原始提交仍然是实验历史的一部分,并且仍然会被引用,因此它不会被垃圾收集——但是在当我以后想要重新设置基础或合并时,两个不同的分支会让生活变得困难,所以这是我想避免的情况。
如何让我的脚本自动检测提交是否有任何分支?
如果简化假设有帮助,我总是在 master 上运行这个脚本,并且我只使用 git 作为本地存储库——我不会在任何地方推送或拉取更改。
该脚本是用 Ruby 编写的,因此我可以使用 git 命令行,也可以使用 git 的 Ruby 绑定——无论哪一种都可以使此任务变得更容易。
I'm writing a script that makes some trivial changes and then commits them to git. Because these are trivial changes, I want to do git commit --amend
whenever I can get away with it -- specifically, when an amend won't "mess up" any other branches' history. If an amend would mess up another branch, I want to do a standard git commit
instead.
For example, if my branches looked like this (a la "Visualize all branch history" in Git GUI):
* [experimental branch] Added feature.
* [master branch] Trivial change from script
* ...
and I'm running this script on the master branch, then I don't want to do an amend, because I would be replacing part of the experimental branch's history. Technically, this won't actually break anything -- the original commit will still be part of experimental's history, and will still be referenced so it won't get garbage collected -- but having nearly-but-not-quite-identical commits in two different branches makes life difficult when I later want to rebase or merge, so it's a situation I want to avoid.
How can I make my script automatically detect whether a commit has anything branched from it?
If simplifying assumptions help, I always run this script on the head of master, and I only use git as a local repository -- I don't push or pull changes anywhere.
This script is in Ruby, so I can either shell out to the git command line, or I can use Ruby bindings for git -- whichever would make this task easier.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
只需运行 gitbranch --contains HEAD 即可获取“包含”此提交的分支列表。如果列表为空,则该提交应该可以安全地进行修改。您可能还需要包含
-a
标志来列出本地和远程分支。或者,您可以将 git rev-parse HEAD 的输出与 git merge-base HEAD other-branch 进行比较。如果这些提交 ID 相同,则当前提交位于 other-branch 的提交历史记录中。
Just run
git branch --contains HEAD
to get a list of branches that "contain" this commit. If the list is empty, that commit should be safe for ammending. You also might want to include the-a
flag to list local AND remote branches.Alternatively, you could compare the output of
git rev-parse HEAD
withgit merge-base HEAD other-branch
. If these commit IDs are identical, the current commit is in other-branch's commit history.提交图是单向的:给定一个提交,您知道它的所有祖先,但不知道它的任何子项。您必须从端点开始并回溯,直到到达所需的提交为止。
使用 git rev-list [some commit] --children (HEAD 是默认值):
左侧列是按时间倒序排列的提交 SHA-1 列表。该提交右侧的任何内容都是该提交的子项 (
--children
)。顶部提交是 HEAD,因此没有子提交。因此,如果您在此列表中 grep 查找 SHA-1 并且它的右侧有任何内容,则它至少有一个子项:
在上面的示例中,commit
6910...
有一个子项,<代码>ef8a...。The commit graph is one-way: given a commit, you know all of its ancestors, but not any of its children. You'll have to start at the endpoints and backtrack until you get to the commit(s) that you want.
Use
git rev-list [some commit] --children
(HEAD is the default):The left-hand column is a list of commit SHA-1s in reverse chronological order. Anything to that commit's right are the children (
--children
) of that commit. The top commit is HEAD and thus has no children.Thus, if you grep for your SHA-1 in this list and it has anything to its right, it has at least one child:
In the above example, commit
6910...
has a child,ef8a...
.