我有一个带有master和a分支的存储库,在这两个分支之间有很多合并活动。当分支A基于master创建时,我如何在我的存储库中找到提交?
我的存储库基本上是这样的:
-- X -- A -- B -- C -- D -- F (master)
\ / \ /
\ / \ /
G -- H -- I -- J (branch A)
我正在寻找修订A,这不是git merge-base(——all)找到的。
我使用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 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中,分支只是历史记录部分提示的当前名称。他们并没有很强的认同感。
这通常不是一个大问题,因为两个提交的merge-base(参见Greg Hewgill的回答)通常更有用,给出两个分支共享的最近一次提交。
依赖于提交的父节点顺序的解决方案显然不适用于在某个分支历史上已经完全集成的情况。
git commit --allow-empty -m root # actual branch commit
git checkout -b branch_A
git commit --allow-empty -m "branch_A commit"
git checkout master
git commit --allow-empty -m "More work on master"
git merge -m "Merge branch_A into master" branch_A # identified as branch point
git checkout branch_A
git merge --ff-only master
git commit --allow-empty -m "More work on branch_A"
git checkout master
git commit --allow-empty -m "More work on master"
如果一个集成合并是反向的父分支,这种技术也会失败(例如,一个临时分支被用来执行一个测试合并到主分支,然后快速跳转到功能分支以进一步构建)。
git commit --allow-empty -m root # actual branch point
git checkout -b branch_A
git commit --allow-empty -m "branch_A commit"
git checkout master
git commit --allow-empty -m "More work on master"
git merge -m "Merge branch_A into master" branch_A # identified as branch point
git checkout branch_A
git commit --allow-empty -m "More work on branch_A"
git checkout -b tmp-branch master
git merge -m "Merge branch_A into tmp-branch (master copy)" branch_A
git checkout branch_A
git merge --ff-only tmp-branch
git branch -d tmp-branch
git checkout master
git commit --allow-empty -m "More work on master"
一个简单的方法是使用选项——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 branch...master
你得到的最后一行是分支上的第一个提交,所以接下来的问题是获取它的父节点。所以
git rev-list -1 `git rev-list branch...master | tail -1`^
似乎为我工作,不需要差异等(这是有帮助的,因为我们没有那个版本的差异)
更正:如果你在主分支上,这是行不通的,但我在一个脚本中这样做,所以这不是一个问题