我有一个带有master和a分支的存储库,在这两个分支之间有很多合并活动。当分支A基于master创建时,我如何在我的存储库中找到提交?

我的存储库基本上是这样的:

-- X -- A -- B -- C -- D -- F  (master) 
          \     /   \     /
           \   /     \   /
             G -- H -- I -- J  (branch A)

我正在寻找修订A,这不是git merge-base(——all)找到的。


当前回答

你可能正在寻找git merge-base:

Git merge-base找到两个提交之间的最佳共同祖先,用于三向合并。一个共同祖先优于另一个共同祖先,如果后者是前者的祖先。没有更好的公共祖先的公共祖先是最佳公共祖先,即合并基。注意,对于一对提交可以有多个合并基。

其他回答

为什么不使用

git log master..enter_your_branch_here --oneline | tail -1

它提供了分支A拥有而master没有的所有提交(..的函数),并且tail -1返回输出的最后一行,这将为您找到指定分支(分支A)的第一次提交。

然后,使用那个提交的SHA

git log enter_the_sha_here^1 --oneline | head -1

它提供了指定提交(^1函数)之前的所有提交,并返回head -1输出的第一行,这是在分支A(又名“分支点”)最早提交之前的“一次提交”。


作为一个单独的可执行命令:

for COMMIT in $(git log --format=format:%H  master..HEAD | tail -1) ; do
    git log $COMMIT^1 --oneline | head -1
done

在分支A (HEAD的功能)中运行上述操作

下面实现了等价于svn log——stop-on-copy的git,也可以用来查找分支的起源。

方法

前往所有分支 收集目标分支和其他分支的mergeBase log和迭代 在mergeBase列表中出现的第一次提交时停止

就像所有的河流都流向大海,所有的分支都流向主人,因此我们在看似不相关的分支之间找到了合并基地。当我们从分支头通过祖先返回时,我们可以在第一个潜在的合并基点上停下来,因为理论上它应该是这个分支的原点。

笔记

我还没有尝试过这种兄弟分支和兄弟分支相互合并的方法。 我知道肯定有更好的解决办法。

详细信息:https://stackoverflow.com/a/35353202/9950。

你可能正在寻找git merge-base:

Git merge-base找到两个提交之间的最佳共同祖先,用于三向合并。一个共同祖先优于另一个共同祖先,如果后者是前者的祖先。没有更好的公共祖先的公共祖先是最佳公共祖先,即合并基。注意,对于一对提交可以有多个合并基。

使用reflog似乎解决了这个问题git reflog <branchname>显示了所有的分支提交,包括创建分支。

这是来自一个分支,该分支在合并回主节点之前有2次提交。

git reflog june-browser-updates
b898b15 (origin/june-browser-updates, june-browser-updates) june-browser-updates@{0}: commit: sorted cve.csv
467ae0e june-browser-updates@{1}: commit: browser updates and cve additions
d6a37fb june-browser-updates@{2}: branch: Created from HEAD

如果你喜欢简洁的命令,

git rev-list $(git rev-list --first-parent ^branch_name master | tail -n1)^^! 

下面是一个解释。

下面的命令提供了在创建branch_name之后发生的master中所有提交的列表

git rev-list --first-parent ^branch_name master 

因为你只关心那些最早的提交,所以你想要输出的最后一行:

git rev-list ^branch_name --first-parent master | tail -n1

最早提交的父文件不是“branch_name”的祖先,根据定义,它在“branch_name”中,并且在“master”中,因为它是“master”中的某个文件的祖先。两个分支中都有最早的提交。

命令

git rev-list commit^^!

只是一种显示父提交引用的方法。你可以用

git log -1 commit^

之类的。

PS:我不同意祖先顺序无关紧要的观点。这取决于你想要什么。例如,在这种情况下

_C1___C2_______ master
  \    \_XXXXX_ branch A (the Xs denote arbitrary cross-overs between master and A)
   \_____/ branch B

将C2输出为“分支”提交是非常有意义的。这是开发人员从“master”扩展出来的时候。当他进行分支时,分支B甚至没有合并到他的分支中!这就是本文给出的解决方案。

如果您想要的是最后一次提交——这样从起点到分支“A”上最后一次提交的所有路径都要经过C,那么您就需要忽略祖先顺序。这纯粹是拓扑学上的,让您了解从何时开始同时运行两个版本的代码。这时您将使用基于merge-base的方法,在我的示例中,它将返回C1。