Git 识别合并到主文件中

Git 识别合并到主文件中,git,version-control,merge,Git,Version Control,Merge,在主分支的历史记录中给定一个commit X,我想确定将该commit包含到主分支中的合并。换句话说,我想找到最大I,使得X是master~I的祖先,即沿着第一个父链的master的第I个祖先。(这假设合并到主节点时,前一个主节点将作为第一个父节点,这通常是afaik的情况。)如何有效地完成这项工作 例子 举个例子,假设我有以下历史记录: A - B - C - D - E - F - G - H \ \ / / I -[J]- K - L - M

在主分支的历史记录中给定一个commit X,我想确定将该commit包含到主分支中的合并。换句话说,我想找到最大I,使得X是
master~I
的祖先,即沿着第一个父链的master的第I个祖先。(这假设合并到主节点时,前一个主节点将作为第一个父节点,这通常是afaik的情况。)如何有效地完成这项工作

例子 举个例子,假设我有以下历史记录:

A - B - C - D - E - F - G - H
     \       \     /   /
      I -[J]- K - L - M
       \         /
        N - O - P
当我想知道何时
J
git合并到master(上行)中时,我希望命令返回
F
。因为从
H
开始,只有第一个父级的历史是
H-G-F-E-…
J
F
的祖先,而不是
E
的祖先。仅仅在范围
J..H
中查找最近的合并是不够的,因为我不想找到
K
L
。由于
L
F
的第二个父级,因此这两个都不是
H
的第一个父级历史的一部分

git log --oneline --merges -1  [<rev range>]
它将根据祖先返回true/false(例如)

因此,首先在master上生成第一个父级合并列表,或者排除有问题的父级合并可以访问的提交,或者使用日期和
--since=
选项。然后,对于顺序中的每一个(通常是最早的第一个),检查您的提交是否是给定合并提交的祖先。您可以使用以下bash脚本:

用于在$中合并(git rev list--reverse--first parent--merges“${commit}”。.master)
如果git merge base--是祖先“${commit}”“${merge}”,则执行此操作
然后git显示-s“${merge}”
打破
fi
完成

提交是一个时间快照,因此提交X只发生一次,不能由以前的提交引入。同样地,以前提交的
diff
(特定变更集)以前也不太可能全部发生。你的意思是-在X之前找到第一个合并提交,同时遵循-第一个父主线,这样你就可以看到在那一点上引入了什么?@PhilipOakley:不,这不是我的意思。我编辑了我的问题,希望这能澄清我的想法。当然,提交只发生一次,但它通常在稍后的时间进入master,即不是在提交时,而是在合并时。我想找到那个合并。不需要是最近的合并,因为最近的合并可能不在主线上。因此,一个简单的
log——第一个父项J..
告诉我
J
C
之前与主项分离,而一个简单的
log——合并J..
(正如您在回答中所建议的)告诉我
K
J
之后的第一个合并,因此,这两个问题都没有回答我的实际问题。在我的答案中添加了额外的注释-如果我有更多的时间,我会尝试一些代码,但希望这些建议能让你达到目的。谢谢,这个祖先检查很有用,尽管我仍然需要循环检查候选人提交,这是我宁愿避免的。我认为,时间戳在某些设置中可能会产生误导,因为它们可能会由于不正确的时钟设置而被修补或破坏。因此,我建议使用一个基于可达性的标准。我在你的帖子中加入了一些代码,希望你不介意。就我个人而言,我会删除
日志--oneline
部分(因为它没有回答问题)和
--since
部分(因为我认为另一个更好),但这是你的帖子,我不想太多干涉。谢谢!我进行了一些RTFM研究,您可能会发现
git rev list--第一个父项--合并--反向..master
符合您的喜好。就拿给出的第一个提交(`head-1`)来说吧(注意,
--max count=
似乎不起作用,因为
--reverse
最后才应用)。这不是我建议生成候选对象的注释吗?无论如何,
--max count
是不合适的,因为在我想要的合并之前,可能有要主控的合并,但是提交输入无法访问这些合并。在我上面的示例中,
C
可能是其他一些功能分支的合并,并将首先打印。所以我不能用这个命令来找到我的解决方案。@MvG,现在我看,是的,它是相似的。我认为需要更多的修订限制。rev list顺序(包括双点符号J..H)应该保证列表中的第一个(反向)是最旧的,它既是合并,也是第一个父链(master!),我认为这是请求。即使
C
是一个合并,它也不在J..H范围内。最大计数可能会被混淆,因为它可能取决于反转,也可能不取决于反转,但它看起来像是在反转之前应用的。尽管如此,这还是构建Git理解的一个有用练习@MvG,尝试添加
--祖先路径
(那些手册可能很难)和GMAN替换(可以通过旧的GMAN id号搜索)
git merge-base --is-ancestor <commit> <commit>