Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
539 views
in Technique[技术] by (71.8m points)

merge - How to identify conflicting commits by hash during git rebase?

When I encounter a merge conflict using git rebase, how can I identify the source of the conflict in terms of commits, rather than just file differences?

I already know how to make (basic) use of git mergetool or git add before git rebase --continue, but sometimes the differences between files just isn't enough: I want to see the commit log and diff of the commit that just failed to be applied to the working tree.

I've read in other questions that git log --merge would show the parent commits if I were using git merge. I tried it anyways when I encountered a conflict and got told fatal: --merge without MERGE_HEAD?.

How can I identify the problematic commit?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Short Answer

If it says

Patch failed at 0001 commit message for F

Then run

$ head -1 .git/rebase-apply/0001
From ad1c7739c1152502229e3f2ab759ec5323988326 Mon Sep 17 00:00:00 2001

To get the SHA ad1c77 of the failing commit, and then use git show ad1c77 to have a look at it.

Long Answer

Let's start with this tree:

A---B---C---D
     
      E---F---G

$ git checkout G
$ git rebase D

When a rebase conflict occurs, it is a conflict between

  • the upstream changes (C--D) from the the common ancestor (B) PLUS the already rebased changes and already resolved conflict (E') versus
  • the patch of the next commit (F)

Let's see what happens:

1) A---B---C---D---E'          <- E patched and committed successfully as E'
2) A---B---C---D---E'---       <- failed to patch F onto E'

Here's the error message:

First, rewinding head to replay your work on top of it...
Applying: commit message for F
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging 1.txt
CONFLICT (content): Merge conflict in 1.txt
Failed to merge in the changes.
Patch failed at 0001 commit message for F

First, you can see that it was F, because the commit message appears. However, if your commit messages all look like "foo", "documentation" or "some fixes", then this won't help, and you really want the SHA id ad1c77 or the contents of the patch.

Here's how to find out the real identity of F:

When it lists the rebase conflict, it will say something like:

Patch failed at 0001 commit message for F

Now look in .git/rebase-apply/, where you will find the patch file 0001:

$ ls .git/rebase-apply
0001          head-name     msg           orig-head     sign
0002          info          msg-clean     patch         threeway
apply-opt     keep          next          quiet         utf8
final-commit  last          onto          rebasing

The patch file includes the original commit-id

$ head -1 .git/rebase-apply/0001
From ad1c7739c1152502229e3f2ab759ec5323988326 Mon Sep 17 00:00:00 2001

You can then look at that.

There must be an easier way, but this works.

Note that the fact that the patch failed may be due to a different commit (if you are rebasing onto a common ancestor of HEAD and the rebase target). Finding that commit is rather more complicated, although you could try doing the rebase in reverse to find it:

$ git checkout D
$ git rebase G

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...