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

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

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

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


当前回答

下面的命令将显示Commit A的SHA1

git merge-base -fork-point A

其他回答

一个简单的方法是使用选项——first-parent来更容易地看到git log -graph中的分支点。

例如,从已接受的答案中取repo:

$ git log --all --oneline --decorate --graph

*   a9546a2 (HEAD -> master, origin/master, origin/HEAD) merge from topic back to master
|\  
| *   648ca35 (origin/topic) merging master onto topic
| |\  
| * | 132ee2a first commit on topic branch
* | | e7c863d commit on master after master was merged to topic
| |/  
|/|   
* | 37ad159 post-branch commit on master
|/  
* 6aafd7f second commit on master before branching
* 4112403 initial commit on master

现在添加——first-parent:

$ git log --all --oneline --decorate --graph --first-parent

* a9546a2 (HEAD -> master, origin/master, origin/HEAD) merge from topic back to master
| * 648ca35 (origin/topic) merging master onto topic
| * 132ee2a first commit on topic branch
* | e7c863d commit on master after master was merged to topic
* | 37ad159 post-branch commit on master
|/  
* 6aafd7f second commit on master before branching
* 4112403 initial commit on master

这样就简单多了!

注意,如果repo有很多分支,你会想要指定两个分支进行比较,而不是使用——all:

$ git log --decorate --oneline --graph --first-parent master origin/topic

我使用git rev-list来做这类事情。例如,(注意3个点)

$ git rev-list --boundary branch-a...master | grep "^-" | cut -c2-

将分叉点吐出来。这并不完美;因为你已经多次将master合并到分支A中,这将分离出两个可能的分支点(基本上,最初的分支点,然后是你将master合并到分支A的每个点)。然而,它至少应该缩小可能性。

我将该命令添加到~/中的别名中。gitconfig:

[alias]
    diverges = !sh -c 'git rev-list --boundary $1...$2 | grep "^-" | cut -c2-'

所以我可以称它为:

$ git diverges branch-a master

像这样的怎么样

git log --pretty=oneline master > 1
git log --pretty=oneline branch_A > 2

git rev-parse `diff 1 2 | tail -1 | cut -c 3-42`^

当然我遗漏了一些东西,但在我看来,以上所有的问题都是因为我们总是试图找到历史上的分支点,这导致了各种各样的问题,因为可用的合并组合。

相反,我采用了一种不同的方法,基于两个分支共享很多历史,分支之前的所有历史都是100%相同的,所以我的建议是向前(从第一次提交开始),寻找两个分支的第一个差异。简单地说,分支点就是找到的第一个差值的父点。

在实践中:

#!/bin/bash
diff <( git rev-list "${1:-master}" --reverse --topo-order ) \
     <( git rev-list "${2:-HEAD}" --reverse --topo-order) \
--unified=1 | sed -ne 's/^ //p' | head -1

它解决了我所有的常规案件。当然,有些边境地区没有被覆盖,但是…你好:-)

您可以检查分支A的reflog,以找到它是从哪个提交创建的,以及该分支所指向的提交的完整历史。Reflogs在.git/logs中。