git 中跨分支的等效更改的簿记清理
我正在尝试清理大量主题分支,主要是为了使 github 中的 master
分支概述不再因存在相同的更改而在非活动主题分支中显示虚假的“n advance”指示符。
如果没有这些虚假指示器,此概述页面将提供一种很好的方法,可以一目了然地查看旧主题分支中的任何提交是否被无意中错过并且没有合并回 master 中。
在下图中,Y
是分支 topic
中的提交,后来作为 Y'
应用于 master
(所以它们有不同的 sha1 哈希值,但补丁 ID 相同)。
A --- B --- C --- Y' --- E <-- master
\
X --- Y <-- topic
gitcherrymastertopic
适当地报告:
- Y
但是,如果我尝试通过从 master
发出 git mergetopic
来清理它,我会遇到合并冲突自从 master
中的更改 E
改变了应用补丁的上下文。
有没有办法告诉master
“嘿,你确实已经有了Y
,所以你可以停止报告你没有。”? (能够以自动/编程方式应用的方式做到这一点是关键。)
I'm attempting to cleanup a large number of topic branches, primarily so that the branch overview for master
in github no longer displays spurious "n ahead" indicators in inactive topic branches due to the presence of identical changes.
Without these spurious indicators, this overview page would offer a great way to see at a glance if any commits from old topic branches were inadvertently missed and not merged back down into master
.
In the diagram below, Y
is a commit in branch topic
that was later applied to master
as Y'
(so they have different sha1 hashes, but identical patch ids).
A --- B --- C --- Y' --- E <-- master
\
X --- Y <-- topic
git cherry master topic
appropriately reports:
- Y
But if I try to clean this up by issuing a git merge topic
from master
, I get a merge conflict since change E
in master
has since altered the context against which the patch applied.
Is there a way to tell master
"Hey, you really do have Y
already, so you can stop reporting that you don't."? (Being able to do this in such a way that it could be applied automatically/programmatically is key.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(3)
由于这是一个公共存储库,因此不想rebase
历史记录,这是一种奇怪的回避方式,但请考虑使用revert
、merge
、和一个计数器恢复
。
在 master
上,分别恢复 E 和 Y' 以将 master
恢复到 C 处的状态(提交消息表明您正在引入一个被遗忘的主题分支,而不是删除更改) :
git revert E
git revert Y'
记下 E 的恢复提交的 sha1,或 git tag revert_E sha1 它。
现在,您将能够将您的 topic
合并到 master
上:
git merge topic
此时主题已正确合并,并且 master
返回到 Y 之前的状态/Y',您现在可以恢复
E 的恢复提交来恢复它:
git revert revert_E
这将完全适用,因为 master
处于与您最初提交 E 时相同的状态(该状态的历史刚刚改变)。感觉有点杂技,但可以解决你的问题。我想不出任何更干净的东西。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
您可以通过将 --cherry-pick 选项传递给 git log 来查看分支之间修订的有效差异。
我最喜欢的咒语是:(
我的别名为
git lr
)。来自 手册页:
永久解决方案#1
为了永久地让 git 不再担心实际上是精心挑选的提交,您可以随时合并其他分支。合并提交将被标记为前一个提交和合并修订树的尖端的子修订。
这告诉修订树遍历在该点停止遍历历史记录。只有当合并来自“其他”分支的修订版时,这样做才是安全的,IFF 你**知道它的所有父项都已被合并(只要你希望它们合并)。
永久解决方案#2
还有一些使用移植的方法。这实际上意味着您将告诉 git - out of band1 - 那某个修订版是另一个修订版的子版本,无需实际重新建立基础/从中合并。
1 就像一个带有 sha1 哈希值对的手写文件:)
这样做的好处是,您不必重写历史记录才能使其发挥作用。但是,如果您愿意,可以使用
git filter-branch
使移植物永久。那么您就不再需要grafts文件了,但是,当然,您将面临必须重写历史记录(并且可能使已发布的修订ID无效)的缺点。未解决问题?
如果所有其他方法都失败了,有时您可能会陷入经常想要合并的远程(主题)分支,但有些差异您根本不想接受。这些可能会一遍又一遍地导致相同的合并冲突。
在这种情况下,我只需指向 git-rerere (重用记录的冲突合并解决方案),这可以使生活变得更加容易,尽管更复杂
You can see the effective difference in revisions between branches by passing the --cherry-pick option to git log.
My favourite incantation runs:
(which I have aliases as
git lr
).From the man page:
Permanent solution #1
In order to permanently make git stop worrying about commits that were actually cherry-picked, you can always merge the other branh. The merge commit will be marked as a child revision of both the previous commit and the tip of the merged revision tree.
This tells the revision tree traversal to stop walking the history at that point. Doing so would only be safe when merging a revision from the 'other' branch IFF you **know that all it's parents have been merged (as far as you would ever want them merged).
Permanent solution #2
There is also some way to use grafts. This really means nothing more than that you'll tell git - out of band1 - that a certain revision is a child of another revision, without having to actually rebase onto/merge from it.
1 as in, a handwritten file with pairs of sha1 hashes :)
The positive thing about this is that you don't have to rewrite history for this to work. However, if you want to, you can use
git filter-branch
to make the grafts permanent. You no longer need the grafts file then, but of course, you'll be back with the disadvantages of having to rewrite the history (and possibly invalidating published revision ids).Loose ends?
If all else fails, sometimes you can be stuck with remote (topic) branches that you frequently want to merge from, but there are differences that you simply never want to take. These would probably result in the same merge conflicts over and over.
In that case I'll just point at git-rerere (Reuse recorded resolution of conflicted merges) which can make life considerably easier, albeit more complicated