Bug 482154 - Merge Tool shows many wrong incoming changes and misses conflicts
Summary: Merge Tool shows many wrong incoming changes and misses conflicts
Status: RESOLVED FIXED
Alias: None
Product: EGit
Classification: Technology
Component: UI (show other bugs)
Version: 4.1   Edit
Hardware: PC Windows 7
: P3 normal with 1 vote (vote)
Target Milestone: 5.12   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 431479 (view as bug list)
Depends on:
Blocks: 441149
  Show dependency tree
 
Reported: 2015-11-13 14:28 EST by Markus Keller CLA
Modified: 2021-07-29 16:30 EDT (History)
5 users (show)

See Also:


Attachments
pre-merged files (for playing with Compare With > Each Other) (31.15 KB, application/zip)
2015-11-20 15:47 EST, Markus Keller CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Keller CLA 2015-11-13 14:28:32 EST
Eclipse SDK 4.2.2 (M20130204-1200)
EGit 4.1.0.201509280440-r

Check out 8955eeca53af81244ce0d8315c5b09108bbed7fb (current HEAD of R4_2_maintenance branch) from git://git.eclipse.org/gitroot/platform/eclipse.platform.ui.git

In History view, cherry-pick e37da30b63cdd33dcf30eb6a5be12657b14a6fd0 

=> Conflicts are reported.

In Git Staging view, open Merge Tool for file E4Application.java (use Last HEAD).

=> The compare editor shows tons of blue ("incoming") changes on the right side, but no conflict. It's impossible to find the actual changes of the cherry-picked commit among all the non-relevant changes.

When you edit the file directly, you see a small <<<< >>>> marked change in the copyright header (not completely accurate, but manageable), and a correctly pre-merged change in saveModel().

The other two files show similar problems.
Comment 1 Thomas Wolf CLA 2015-11-17 17:31:17 EST
cgit doesn't do better on E4Application.java in this cherry-pick (tried both 2.6.3 and ancient 1.7.7.5). It gives exactly the same conflict in the copyright header, and no diff whatsoever involving :1:, :2:, :3:, and working tree will show you only the header lines as a conflict (or as additions).

The EGit Merge Tool shows the diff between HEAD (8955ee) and CHERRY_PICK_HEAD (e37da). (I.e., between :2: and :3:)

Selecting on the workspace resource "Compare with HEAD Revision" gives a better diff between the workspace file (merge result with the conflict in the header) and HEAD (which is shown as the last commit that touched the file in HEAD's tree, 80e45e). That diff shows the header conflict and the successful auto-merge in saveModel(). It's the same diff as you get in cgit with

git diff :2:bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/E4Application.java bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/E4Application.java

So, what exactly is the bug here in your opinion?
Comment 2 Markus Keller CLA 2015-11-20 15:47:11 EST
Created attachment 258191 [details]
pre-merged files (for playing with Compare With > Each Other)

(In reply to Thomas Wolf from comment #1)
Thanks for the confirmation and comparison with cgit.

> So, what exactly is the bug here in your opinion?

The bug is that the compare editor is not very helpful in this situation. I'd expect to only see changes in the two sections that I see when comparing the pre-merged file on disk with HEAD.

But I have to admit I can't tell right away how to best solve this. Let me try:

The Merge Tool (use HEAD) opens a 3-way editor that shows:
- left: HEAD
- right: cherry-picked commit
- ancestor: first common ancestor of current branch and cherry-picked commit

I think the problem is that the common ancestor is too far away from the cherry-picked commit, and that nothing tells me which of the many differences are actually due to the picked commit.

I think this is the compare editor that should be shown:
- left: pre-merged file with conflicts resolved by taking the lines from
        HEAD (i.e. those between <<<<<<< and =======)
- right: pre-merged file with conflicts resolved by taking the lines from
         the cherry-picked commit (i.e. those between ======= and >>>>>>>)
- ancestor: HEAD

I've attached a ZIP with these states in separate files, so you can try it out: Select HEAD.java and the two pre-merged files, choose Compare With > Each Other, and select HEAD.java as ancestor.
=> The <<<<<<< and >>>>>>> changes are clearly visible, and the pre-merged changes show up as pseudo-conflicts (if enabled on the Compare prefs page).

I don't have much experience which such merges, so I can't really tell if that should just be an additional mode in the Merge Tool, or if it should be the default or even the only mode.
Comment 3 Matthias Sohn CLA 2015-11-20 18:54:01 EST
if we want to improve the merge tool we should have a close look at how p4merge displays merges, to my experience it's the best merge tool I am aware of, it also provides 4 panes for base, the 2 heads to be merged and a 4. pane for the working tree version. I always use that if I don't understand a complex merge with conflicts.

See the attached screenshot for your example
Comment 4 Matthias Sohn CLA 2015-11-20 18:58:03 EST
here the screenshot
Comment 5 Matthias Sohn CLA 2015-11-20 18:58:11 EST
http://imgur.com/LPdUl9U
Comment 6 Thomas Wolf CLA 2015-11-22 13:30:42 EST
A cherry-pick is a three-way merge between

1. the target commit (8955ee in this case, stage 2 in index after failed merge)
2. the cherry-picked commit (e37da, stage 3 in index after failed merge)
3. using the cherry-picked commit's parent as "common" ancestor (8b8290 in this case; stage 1 in index after failed merge)

Additionally, we have the pre-merged result in the working tree.

We don't have the versions "conflicts only against head" or "conflicts only against cherry-picked commit".
Comment 7 Mauro Molinari CLA 2021-04-07 04:04:33 EDT
I'm quite new to git but used Subversion a lot. Today I found this problem of EGit and was first going to blame git, but I then discovered the problem lies in EGit merge tool indeed.

I experience the same problem described by Markus Keller, cherry-picking a commit from another branch, the merge tool shows a lot of unrelated changes as "incoming" non-conflicting changes: this is the problem.

When performing an "Edit Conflict" with Subversion (this indeed works with Subversive for sure, almost certainly with Subclipse, and I'm pretty sure it worked for CVS as well, although so much time as passed since the last time I used it), the compare editor shows three type of changes:
- changes in BLUE are indeed incoming non-conflicting changes, i.e. the changes you should apply to your local file and which can be cleanly applied
- changes in RED are conflicting changes, the ones you should solve manually
- ===> IMPORTANT: changes in WHITE are non-related changes that exist between the two files and that are unrelated to the diff you're trying to merge and that, generally speaking, should just be ignored, although they are there to display the actual context of what you are doing

When performing a "Copy All Non-Conflicting Changes from Right to Left", only BLUE changes are copied, NOT the WHITE changes. This leads to a correct merge resolution: you copy all non-conflicting changes and then solve manually the conflicting ones. The white changes are simply to be ignored (unless you have a valid reason to take them all or in part, of course, but you should do it manually and for a reason).

With EGit, instead, I'm cherry-picking a very small change from another branch: the change consists on just the addition of a method at the bottom of the file, but it's conflicting because the branch I'm merging from contains another "last but one" method which does not exist on my working tree. The merge tool however shows me tons of BLUE changes, no white changes and even NO red changes. If I do a "Copy All Non-Conflicting Changes from Right to Left", since all diffs are blue the final result is that all the file contents of the source branch is copied to my working tree, which is of course not what I want to do.
Indeed, although the compare editor seems to be in "three-way compare" mode, I would say that the Merge Tool is actually NOT showing me a three-way compare, but a plain two-way compare between the file state at the target commit and my local state.

This is indeed quite a serious problem IMHO. In this particular case fortunately going "the manual way" (by fixing <<<<<<< and >>>>>>> text regions) is quite easy, but in other more complex cases the value added by the Eclipse Three-Way Compare Editor would be extremely important to successful resolve conflicts.

Please, please, consider fixing this problem. I don't have any insight on how the compare editor works, but perhaps it's just a wrong way of driving it when invoking the Merge Tool, because the functionality DOES exist for sure.
Comment 8 Thomas Wolf CLA 2021-04-19 06:08:28 EDT
Took another look at this. The main problem here is that the base commit used in the Eclipse merge editor is wrong for a cherry-pick.

As mentioned in comment 6
> A cherry-pick is a three-way merge between
> 
> 1. the target commit (8955ee in this case, stage 2 in index after failed
> merge)
> 2. the cherry-picked commit (e37da, stage 3 in index after failed merge)
> 3. using the cherry-picked commit's parent as "common" ancestor (8b8290 in
> this case; stage 1 in index after failed merge)
> 
> Additionally, we have the pre-merged result in the working tree.

So far, so good; it's exactly what C git also does. (1 is the HEAD when the cherry-pick is done.)

But as mentioned in comment 2
> The Merge Tool (use HEAD) opens a 3-way editor that shows:
> - left: HEAD
> - right: cherry-picked commit
> - ancestor: first common ancestor of current branch and cherry-picked commit

So EGit uses dd59f71 as base for the Eclipse merge editor, not 8b8290. As a result the merge editor displays an entirely different three-way merge than what the cherry-pick actually did.

This is a bug in GitMergeEditorInput; it can be fixed reasonably easily.
Comment 9 Eclipse Genie CLA 2021-04-19 13:04:33 EDT
New Gerrit change created: https://git.eclipse.org/r/c/egit/egit/+/179520
Comment 10 Mauro Molinari CLA 2021-05-20 04:18:05 EDT
Really looking forward for this fix: what's its state?
Thanks Thomas!
Comment 11 Thomas Wolf CLA 2021-05-20 06:35:32 EDT
(In reply to Mauro Molinari from comment #10)
> Really looking forward for this fix: what's its state?

Planned for EGit 5.12; currently in review in Gerrit.
Comment 13 Thomas Wolf CLA 2021-07-29 16:30:24 EDT
*** Bug 431479 has been marked as a duplicate of this bug. ***