Suggesting a new feature: FourDiff - a new way to resolve merge conflicts

Hi!

I just opened this pull request on GitHub. I then remembered that all development is on GitLab and closed it. However, on GitLab I can’t fork the repository (it says “Limit reached You cannot create projects in your personal namespace. Contact your GitLab administrator”). Anyway, I really hope it can be added to meld. Here’s the description from the GitHub PR:

This PR adds another diff view, called FourDiff. I have been using it for resolving merge conflicts since 2018, and it helped me a lot - before I made it, resolving merge conflicts was a chore that I never fully understood how to do, and now it’s usually pretty easy, and I feel confidence when resolving conflicts.

The key idea is that when merging/rebasing/cherry-picking/reverting, you want the diff between LOCAL and MERGED to be logically the same as the diff between BASE and REMOTE. The FourDiff view displays those two diffs side-by-side, which allows to visually verify that they are logically the same diff.

This is a new feature, so I’ll be happy to get any feedback on it. I hope it can be added to Meld, since I think it can help others like it helped me.

To see it in action, I created a simple merge conflict example. You can see it like this:

cd /tmp
git clone https://github.com/noamraph/conflict-example.git
cd conflict-example
git merge origin/remove-greetings
# Shows: Automatic merge failed; fix conflicts and then commit the result.
git mergetool -t meld

It shows something like this:
image
For me it is very confusing. In truth, there’s no way to know what the result should be just from the two side panes.

To see the FourDiff view, checkout the fourdiff branch, add this to ~/.gitconfig:

[mergetool "fourdiff"]
    cmd = /PATH/TO/meld/bin/meld "$REMOTE" "$BASE" "$LOCAL" "$MERGED"

And run:

git mergetool -t fourdiff

You get this (without the red arrows, of course):

The panes are, from left to right: REMOTE, BASE, LOCAL, MERGED. Resolving the merge means making the diff from LOCAL to MERGED be the same as the diff from BASE to REMOTE.

We can see that the diff between BASE and REMOTE removed the name arguments and the print() calls. It’s easy to edit the right pane to do the same:

What I really like about this view is that since the diffs appear side-by-side, it’s immediately visible that the two diffs are logically the same.

Another feature that helps with understanding and resolving the merge conflict is the ability to switch the view to show the difference between BASE and LOCAL. If you press Ctrl-T (or click View->Toggle FourDiff View), you see this:
image

This shows the difference between BASE and LOCAL, which caused the merge conflict. We can see that the difference is adding the c argument to multiply(). This change needs to be preserved when resolving the conflict.

The implementation of FourDiff is quite simple - the FourDiff widget holds three FileDiff widgets:

  1. REMOTE - BASE
  2. BASE - LOCAL
  3. LOCAL - MERGED

There are two views: In the first view, FileDiffs 1 and 3 are visible, and in the second view, FileDiff 2 is visible.

When one of the two BASE panes is scrolled, the other is scrolled to the same position, and so with the two LOCAL panes. This causes all panes to be scrolled together, since the two panes in all three FileDiffs are already scrolled together.

Note: I made only the rightmost pane (MERGED) editable. It is required that the shared panes will not be editable, so their text will remain in sync. It was possible to be more symmetric, and treat the leftmost and rightmost panes in the same way, allowing both to be editable. However, I preferred to break the symmetry and only make the rightmost pane editable. My main reason was that I made the “next conflict” and “previous conflict” actions go the the next and previous <<<<<<< in the right pane, so it already broke the symmetry. But this is open for debate.

What do you think? Can this be added, even as an experimental feature?

Thanks!
Noam

1 Like

Some images in above post are not displayed, as they’re shown as expired AWS resource.

Thanks! I think I fixed it.

(The limitations on new users are pretty, well, limiting.)

Sorry it took me so long to get to this! It’s a complex feature so I needed to actually look at it and think about how it’s supposed to be used.

I’ll start by saying that I think that this is a neat idea and a novel (at least to me) way to think about resolving merge conflicts. I like that you’ve restricted edits to avoid some weird sync issues, and I think that having the third toggleable comparison is a smart addition.

When I look at your example of a confusing merge comparison, I completely agree that it’s not ideal. The thing is that Meld already has an improved option here, it’s just that a lot of people don’t know about it because it’s not directly supported by git mergetool. The three-way comparison view you get when launching from a version control comparison already does some of what you’re looking for, by replacing the conflict area with a conflicted base portion.

I have in the past spent time working on a feature that allows variably hiding panes to get the same kind of effect you’ve gone for with the toggleable middle diff. These attempts always ended up being very invasive so I never managed to land them, but I think that ultimately they’re a good idea. However, for now your solution is honestly very elegant, and I’m considering adopting it for the existing merge view.

My current inclination is to try and take some ideas from your work and use them to make the existing merge view better, but I maybe need to actually use your approach for a few tricky merges to know for sure.

If there’s specific things that you don’t get out of the current version-control-launched merge view (or if you didn’t know about it) then I’d love to hear a bit more about that. It’s been a long pet issue that we don’t provide an easy way to launch into that view directly via git mergetool, and I’d love to fix that problem.

I would absolutely encourage you to put up an MR on Gitlab, even just so that your work doesn’t get lost. If you continue to have trouble with it, let me know and I’ll figure something out.

Hi Kai,

Thanks for the reply, and sorry for my late response…

I now tried again, and GitLab let me open a MR. So I just copied the MR from GitHub. It’s here: Add FourDiff - a new way to resolve merge conflicts (!128) · Merge requests · GNOME / meld · GitLab

My current inclination is to try and take some ideas from your work and use them to make the existing merge view better, but I maybe need to actually use your approach for a few tricky merges to know for sure.

Please do try using my approach! At least to me, it makes resolving conflicts so much easier than other views I’ve seen. And it works in exactly the same way for cherry-picks and reverts, where I’m not sure what the 3-way view should actually show in those cases.

If there’s specific things that you don’t get out of the current version-control-launched merge view (or if you didn’t know about it) then I’d love to hear a bit
more about that. It’s been a long pet issue that we don’t provide an easy way to launch into that view directly via git mergetool, and I’d love to fix that problem.

I actually don’t know about another view - all I know is that I can run git mergetool. How can I get another view? (The docs say to just use git mergetool).

My MR changes very little outside of the main fourdiff.py file. Perhaps the fourdiff view can be added, with a banner on top saying something like “This view is experimental, please provide feedback at [a suiteable link]”? Then more people would be able to experiment with it, without it being considered a core supported feature of Meld.

Thanks!
Noam

I actually don’t know about another view - all I know is that I can run git mergetool. How can I get another view? (The docs say to just use git mergetool).

(Just responding to this for the moment, since I haven’t had a chance to properly play with fourdiff)

Meld’s version control view is launched by starting Meld on the git folder itself (i.e., normally just meld . if you’re in the repo). From there, files in the conflict state are indicated in red. If you open a conflict from there, you get the three-way-with-ancestor view.

This topic was automatically closed 45 days after the last reply. New replies are no longer allowed.