1

I merged 2 branches and got conflicts. One of them is just a mess because it was strongly re-factored on one branch (B1). However, I expect the other branch (B2) to contains a simple change that, unluckly, affected many lines.

So I think the easiest way to do the merge, is to keep B1, and re-do the changes done on B2. But I want to be sure of what are those changes on B2 before starting that, to be sure I don't forget anything.

To do so,

  • I want to know the latest common ancestor commit for this file between the 2 branches
  • ideally, I'd like to do it in my current "conflicting-merge" situation without having to checkout
Juh_
  • 14,628
  • 8
  • 59
  • 92

2 Answers2

6

Note that while you are in the process of hand-merging some conflicted file file.ext, all three versions of that file are stored in the index / staging-area, in the three slots reserved for this case. They are numbered:

  • slot 1 holds the base version;
  • slot 2 holds the --ours version from the HEAD commit;
  • slot 3 holds the --theirs version from the other commit.

While git checkout has --ours and --theirs to extract those two versions, it is missing an option for the base version. However, git show can be used to extract all three versions:

git show :1:file.ext > file.ext.base
git show :2:file.ext > file.ext.ours
git show :3:file.ext > file.ext.theirs

for instance.

If you ever use the git mergetool command, it is simply a shell script wrapper that does the above (using slightly different names), then runs your selected merge tool on those three files.

torek
  • 448,244
  • 59
  • 642
  • 775
  • interesting, tx for the info. However here I really need to compare `theirs` with `base` (on the whole file preferably) because the changes cannot be applied to the refactored `ours`. – Juh_ May 22 '18 at 15:13
  • 1
    If you extract all three as in the above `git show` commands, you can diff the .base and the .ours variants (with `git diff` if you like; add `--no-index` if you've put both files outside the work-tree, e.g., in /tmp). – torek May 22 '18 at 16:40
  • looking into this slot system I found another of your answer that gives more details. I share it for other interested people: https://stackoverflow.com/a/21311271/1206998 – Juh_ May 25 '18 at 08:13
  • you're a life saver bro. never managed to get the BASE without this – Amin Oct 09 '18 at 17:00
  • 2
    @Amin: consider setting `merge.conflictstyle` to `diff3`: Git will include the lines from the merge base in the conflicted work-tree version. – torek Oct 09 '18 at 18:22
0

I just remembered it:

git merge-base B1 B2

give the common ancestor of branches B1 and B2. This is for the whole branches. But no later change applies on any file on both branches.

Then, to see the diff, just

git diff common_ancestor..B2 path/to/the/file 

where common_ancestor is the commit obtained with git merge-base

Juh_
  • 14,628
  • 8
  • 59
  • 92