我想仅列出合并提交,通过该提交,给定文件实际上将其作为当前分支。举个例子:
-A--B----C-------D--E------F----G--------H---
\ \---P--Q--/ \---X--Y--/ /
\-----------------------------M-----/
让我们说P和Y是修改abc.txt的唯一提交。在这种情况下,如何让git log仅列出D和G?请注意,D和G实际上并没有直接触及abc.txt:它们只是具有触及abc.txt的祖先的合并提交。
我试过了:
git log --merges -m --name-only --follow abc.txt
不幸的是,这也包括H,因为H曾经触及(通过Y)abc.txt的祖先(G)。
答案 0 :(得分:1)
你不能,至少不能直接。 (我认为 - 这是基于--simplify-merges
显然没有做你想要的事实。通常看起来它会做你想要的。注意你需要--simplify-merges
和 --merges
此处;您将在“第一”步骤中的--simplify-merges
中使用--merges
但不使用git rev-list
。)
请注意,D和G实际上并没有直接触及abc.txt:它们只是具有触及abc.txt的祖先的合并提交。
嗯,是的,不是。像Git中的任何提交一样,合并提交有一个树和一些父。提交D和G,合并,至少有两个父提交。每个父母也有一棵树,所以我们可以差异(或者有Git diff)D ^ 1(即C)vs D,和D ^ 2(即Q)vs D.其中一个 - 第一个,如果我让两个父母正确订购 - 将显示对abc.txt
的更改。我们可以以相同的方式将G ^ 1和G ^ 2中的每一个与G相区分并获得相同的效果。但我想我们都知道你的意思:我们以这种方式发现的变化因某些早期提交而存在。
但对于H来说也是如此!差异H ^ 2(又名M)与H显示对同一文件的更改。这种变化是通过G引起的,就像G通过Y引起的变化一样。那么问题就变成了:我们为什么要算G,但不算H?
我认为我们应该计算G的原因而不是H这里的原因是 - “带来”变化的祖先 - 即Y-具有“下游”提交,即G,这是一个合并,我们想声称“吸收”变化。
(根据同样的逻辑,如果M也改变了abc.txt
,那么我们希望将H包括在我们的集合中。)
如果这种推理是正确的,那么这就建议了一种找到你关心的合并的算法:
abc.txt
的合并提交版本与两个父版本不同,请将合并标记为集合中的“肯定包含”:我们从“双方”引入了更改和/或这是一个“邪恶的合并”(它引入了在父叉中没有做出的改变)。但是,如果没有,请将合并标记为“可能可移除”。最后,以“最父母 - y”的顺序遍历所有“可能可移动”的合并(在任何孩子之前做所有父母:你将自然地从适当的git rev-list --topo-order --reverse
中获得第一步,或者您可以按其他顺序获取列表,然后反向工作)。任何标记为“绝对保留”的提交;标记为“可能保留,可能是可移动的,取决于父级#N”的任何提交都将保留,除非它具有与父级相同的相同 abc.txt
的父级合并-in-那个方向;并且任何标记为“可能保留,可能是可移动的”的内容都会被删除,如果它具有保持父方向的方向具有相同的abc.txt
。
(我不确定如何为章鱼合并修改这个,所以我会考虑给你。)