简体   繁体   English

git cherry / git log-樱桃合并合并

[英]git cherry / git log --cherry confused by merges

I've got two branches, with a commit cherry-picked from one branch to the other. 我有两个分支,从一个分支到另一个分支都经过精心挑选。 Like so: 像这样:

> git init
Initialized empty Git repository in foo/.git/
> touch foobar; git add foobar; git commit -m "initial commit"
[master (root-commit) d109ffc] initial commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foobar
> git branch somebranch
> echo a >> foobar; git add foobar; git commit -m "add a"
[master 1527212] add a
 1 file changed, 1 insertion(+)
> touch anotherfile; git add anotherfile; git commit -m "add blank anotherfile"
[master 84821fc] add blank anotherfile
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 anotherfile
> git checkout somebranch; git cherry-pick -x 1527212
Switched to branch 'somebranch'
[somebranch b59ad0a] add a
 Date: Sat May 13 15:41:16 2017 +0800
 1 file changed, 1 insertion(+)
> git tree somebranch master
* b59ad0a (somebranch) add a
| * 84821fc (HEAD -> master) add blank anotherfile
| * 1527212 add a
|/
* d109ffc initial commit

At this stage, git cherry and git log --cherry --oneline display what I'd expect: 在这个阶段, git cherrygit log --cherry --oneline显示我所期望的:

> git cherry somebranch master
- 1527212b9047f882c7438d083505941c47ea9a5b
+ 84821fcb3d33d41b64dddcc56728dd3e22466e4a
> git log --cherry --oneline somebranch...master
+ 84821fc (HEAD -> master) add blank anotherfile
= 1527212 add a

However, if I merge the two branches back together, I lose this output - both git cherry and git log --cherry fail to recognise the cherry-picked commit as identical: 但是,如果我将两个分支合并回去,则会丢失此输出git log --cherry git cherrygit log --cherry无法识别出挑选出的提交是相同的:

> git checkout master
Already on 'master'
> git merge somebranch
Merge made by the 'recursive' strategy.
> git tree
*   90810f6 (HEAD -> master) Merge branch 'somebranch'
|\
| * b59ad0a (somebranch) add a
* | 84821fc add blank anotherfile
* | 1527212 add a
|/
* d109ffc initial commit
> git cherry somebranch master
+ 1527212b9047f882c7438d083505941c47ea9a5b
+ 84821fcb3d33d41b64dddcc56728dd3e22466e4a
> git log --cherry --oneline somebranch...master
+ 84821fc add blank anotherfile
+ 1527212 add a

Is there a way I can get git to show that these commits are the same, even though they've been merged back together? 有没有办法让我git证明这些提交是相同的,即使它们已经合并在一起了?

The problem comes about because Git no longer looks at one of the commits. 由于Git不再查看提交之一,因此出现了问题。

Remember that the three-dot syntax (implied in the case of git cherry AB , explicit in the case of git log --cherry A...B ) means to take a symmetric difference: commits reachable from either A or B , but not from both. 请记住,有三个点的语法(在的情况下,隐含git cherry AB ,在明确的情况下, git log --cherry A...B )是指采取对称差: 无论从提交到达A B ,但不从两个。

(I assume git tree here is an alias for git log --all --decorate --oneline --graph :) (我认为这里的git treegit log --all --decorate --oneline --graph的别名:)

 > git tree * 90810f6 (HEAD -> master) Merge branch 'somebranch' |\\ | * b59ad0a (somebranch) add a * | 84821fc add blank anotherfile * | 1527212 add a |/ * d109ffc initial commit 

The name master means 90810f6 , and the name somebranch means b59ad0a . 名称master表示90810f6 ,名称somebranch表示b59ad0a The first thing we have to do is find commits that are reachable from these two commits, keeping in mind just how we reached them: 我们要做的第一件事是找到这两个提交可以到达的提交,并牢记我们如何到达它们:

  • 90810f6 : reached from 90810f6 1 90810f6 :从90810f6到达1
  • b59ad0a : reached from both b59ad0a and 90810f6 : discard b59ad0a :从b59ad0a 90810f6都达到:丢弃
  • 84821fc : reached from 90810f6 84821fc :从90810f6到达
  • 1527212 : reached from 84821fc 1527212 :从84821fc到达
  • d109ffc : also reached from both sides: discard d109ffc :也从双方到达:丢弃

We've tossed out the one interesting (cherry-equivalent) b59ad0a commit already, so we never see it. 我们已经放弃了一个有趣的(相当于樱桃的) b59ad0a提交,因此我们再也看不到它。

As the documentation tells us, --cherry is: 文档所示--cherry是:

A synonym for --right-only --cherry-mark --no-merges ... --right-only --cherry-mark --no-merges同义词...

so from our list of three not-yet-discarded commits, we toss out 90810f6 as well, as it is a merge. 因此,从我们三个尚未丢弃的提交列表中,我们也将90810f6了,因为它是合并。 That leaves the two commits we do see. 剩下的两次提交,我们看见

Is there a way I can get git to show that these commits are the same, even though they've been merged back together? 有没有办法让我git证明这些提交是相同的,即使它们已经合并在一起了?

You must start the inspection from just below the merge. 您必须从合并的正下方开始检查。 Use any method (see the gitrevisions documentation for the many ways to spell this) to start the listing from the first parent of the merge commit that master identifies, eg: 使用任何方法(有关多种拼写方法,请参见gitrevisions文档 )从master标识的合并提交的第一个父级开始列出,例如:

git log --cherry --oneline somebranch...master~1

(which we know only because we looked at the graph and saw that master was the merge). (我们之所以知道是因为我们查看了图表并看到master是合并对象)。 Note that we can specify both of the two commits that fed into the merge using the ^1 and ^2 suffixes: 请注意,我们可以使用后缀^1^2指定两个提交合并的提交:

git log --cherry --oneline master^2...master^1

The notation master^1 and master~1 mean exactly the same thing, since each says to move back one step to the first parent. master^1master~1含义完全相同,因为它们各自表示都向后移到第一个父级。 This is not the case for master^2 vs master~2 : the former means "second parent" while the latter means "first parent of first parent". 这是不适合的情况下master^2 VS master~2 :前者是指“第二个亲本”,而后者是指“第一个亲本的第一个亲本”。


1 A commit always reaches itself, even if that sounds vaguely suggestive. 1承诺总能达成,即使听起来含糊不清。 :-) :-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM