1

I am doing a cherry-pick that resulted in a merge conflict and when I resolve it, the default merge tool, Vimdiff, is opened. With 4 panes, the top being the Local , base , and remote. However I noticed the base doesn't have the version of the file that I would expect to see if did git merge-base between the local and the remote commit. Is this is a defect in git/vimdiff how can I see which commit is being shown in the base pane ?

dgunc
  • 25
  • 2

1 Answers1

1

vimdiff does not know the merge base commit hash ID; Git does not tell vimdiff what it is. In fact, the hash ID is not visible anywhere: Git keeps it secret.

However, you started your question text body with this:

I am doing a cherry-pick

so you can easily find the merge-base commit hash ID: it's the parent of the commit you're cherry-picking.

Is this is a defect in git/vimdiff ...

That's somewhat of a matter of opinion, I imagine. (I do kind of wish Git left a MERGE_BASE_HEAD file or some such—vimdiff itself still wouldn't see it, but you could write vim scripts to show it, or just run git rev-parse in another window or after suspending the editor.)

... if did git merge-base between the local and the remote commit

That would be likely to give you a different commit. Cherry-pick works by artificially forcing the merge base commit to be the (single) parent of the to-be-picked commit:

...--*--o--P--C--o--o   <-- some-branch
      \
       A--B   <-- your-branch (HEAD)

If at this point you run git cherry-pick <hash-of-C>, the "merge base" for this merge is commit P, not commit *.

Running git merge-base your-branch some-branch would report the hash ID of commit *, but that's not the merge base of this merging-action. Git needs to take the changes from P to B as "your changes" to be applied to P, and combine those with their changes from P to C.

torek
  • 448,244
  • 59
  • 642
  • 775
  • would be interesting to know what it means to have the changes from P to B. I assumed the cherry-pick would be just the changes that are just in C that would be applied to B if it makes sense otherwise its some sort of conflict. do you mean the changes "between" P and B as there is no path between P and B. – dgunc Apr 20 '20 at 00:50
  • Paths are not relevant in merge operations. Merge just takes two diffs: base vs left/local/ours, and base vs right/remote/theirs. It then combines these diffs and applies them to the *base* version. Without applying `P`-vs-`B` here, your new commit would just be a direct copy of the saved snapshot in commit `C` itself. That is, Git is not applying `P-vs-C` to `B`, it's combining `P`-vs-`B` with `P`-vs-`C`, and applying that to *`P`*. – torek Apr 20 '20 at 01:01
  • The end result matches what you'd get if Git *did* apply `P`-vs-`C` to `B` ... except that by doing a merge, Git can handle some conflict cases better. – torek Apr 20 '20 at 01:02