2

I've seen https://stackoverflow.com/a/49215221/962918 which gets close to half of what I'm wanting, with git rebase --show-current-patch. Like that question, I'm interactively rebasing my current HEAD branch onto one of the commits in it's history to clean them up (aka, sort into logical steps) before publishing them publicly. Often times, merge conflicts happen as the interactive rebase runs.

In my current mental model, the goal of resolving these rebase conflicts is to generate the resulting end state of applying the changes (aka, patch/diff) of each of the two commits rebase is trying to combine. This is different than a standard merge conflict, where the end goal is to generate an end state that is a harmonization (combination) of the end state of two commits at the tips of the branches you are merging.

Because this is a rebase, the changes (diff/patch) from these commits are being applied to a different starting state then they originally were. I get that this could cause trouble that may need manual resolution. (For example, what if the function the patch is trying to change has been deleted?)

If the goal is to apply two sets of changes, then visualizing them seems useful to solving a rebase conflict. I am aware of the git difftool and git mergetool commands, and really appreciate Meld's display of differences. How can I get Git to show me these two sets of changes, with the full context of the before and after contents of the files with git difftool? git rebase --show-current-patch seems to get me one set of changes, but not in Meld. And how do I have the other set of changes displayed in Meld (or whatever the preferred diff (or merge) tool is? Bonus points if I can get a 3rd file passed to Meld so I can edit/create the "merged" version from Meld.

Azendale
  • 675
  • 1
  • 7
  • 17
  • In fact, if interactive rebase is just cherry picking one set of changes (commit) at a time, where is this second set of changes coming from? – Azendale Apr 19 '23 at 01:36
  • In conflicts from a normal merge, the BASE file is the most recent common ancestor (findable by using `git merge-base` between the two branches you are trying to merge. What merge-base is git using here for BASE, since it seems that there are really two sets of changes? – Azendale Apr 19 '23 at 01:37
  • 2
    For a cherry-pick (and rebase is a sequence of cherry-picks), the merge-base is the parent of the cherry-picked commit. – j6t Apr 19 '23 at 05:43
  • So is it fair to say then that the second set of "changes" is the diff/patch between the HEAD (last commit the interactive rebase wrote; what it is trying to apply this patch on top of) and cherry-picked's parent? – Azendale Apr 19 '23 at 05:59
  • That sounds correct. – j6t Apr 19 '23 at 06:04

1 Answers1

2

a. as correctly mentioned by @j6t in a comment: the "merge base" in a cherry-pick is the parent of the original commit.

In the middle of a rebase, that commit is referenced by REBASE_HEAD, so you can view :

# "ours" :
git diff REBASE_HEAD~ HEAD

# "theirs" :
git diff REBASE_HEAD~ REBASE_HEAD

b. you mentioned git mergetool and meld's 3 way merge display:

one minor point about meld's way of handling 3 way merge is that it shows 3 panes (not 4), so if you try to reconcile changes in the middle pane, you loose the original content of BASE.

kdiff3, for example, shows 4 panes: 1 for each of "ours", "base", "theirs", and a 4th one to buffer your conflicts resolution (e.g: the actual content of the file you will save at the end).

Out of habit I got used to the interface of meld, so I wrote a wrapper command around meld, to first make use of its --auto-merge feature (which is IMHO precious), and second to open extra tabs for each of the diffs "ours" and "theirs" :

# I named my alias 'meld3', here are the two relevant config settings:
$ git config --list | grep meld3

# --diff, which can be specified several times, will open extra diff tabs
# I added one to view 'LOCAL vs BASE' (LOCAL is on the left side) and
# one to view 'BASE vs REMOTE' (REMOTE is on the right side)
mergetool.meld3.cmd=meld --auto-merge $LOCAL $BASE $REMOTE -o $MERGED \
    --diff $LOCAL $BASE --diff $BASE $REMOTE

# use the above command as the default mergetool:
merge.tool=meld3
LeGEC
  • 46,477
  • 5
  • 57
  • 104