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:
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:
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:
- REMOTE - BASE
- BASE - LOCAL
- 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