Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Compare » Merging conflicting models?
Merging conflicting models? [message #1168809] Sun, 03 November 2013 15:38 Go to next message
Alan DW is currently offline Alan DWFriend
Messages: 108
Registered: March 2012
Senior Member
Hello everyone,

I'm in the typical "repository" situtation: I have a local model in the state as it was when it was last synchronized with the server (the "common ancestor"), the model as it is now ("left") and the latest version of the model from the server ("right"). I need to perform a local update operation, which means that I must merge the server version and the current client version, with the last synchronized client version as the common ancestor.

After obtaining the "Comparison" object from the three-way-compare, how do I merge the differences? To start off, I'd like to merge only the non-conflicting differences. The BatchMerger states in its Javadoc that it will merge *all* differences, regardless whether they are conflicting or not. What's the preferred way to merge all non-conflicting changes?

After merging the non-conflicting changes, I have a callback to let the user decide which version of the conflicting element (left or right) he wants to use. I tried to do this in the following way:


                        IMerger.Registry registry = EMFCompareRCPPlugin.getDefault().getMergerRegistry();
			IBatchMerger merger = new BatchMerger(registry);
			PseudoConflictMerger pseudoConflictMerger = new PseudoConflictMerger();
                        
                        //TODO merge all non-conflicting changes - but how?

			for (Conflict conflict : comparison.getConflicts()) {
				if (conflict.getKind() == ConflictKind.PSEUDO) {
					// don't do anything except for marking it as merged
					for (Diff diff : conflict.getDifferences()) {
						pseudoConflictMerger.copyLeftToRight(diff, new BasicMonitor());
					}
				} else {
					// call the callback operation
					MergeConflictResolution resolution = conflictResolver.resolve(conflict);
					switch (resolution) {
						case USE_MINE:
							merger.copyAllRightToLeft(conflict.getDifferences(), new BasicMonitor());
							break;
						case USE_THEIRS:
							merger.copyAllLeftToRight(conflict.getDifferences(), new BasicMonitor());
							break;
						default:
							throw new RuntimeException("Unknown MergeConflictResolution type: " + resolution);
					}
				}
			}



This seems rather tedious to me, given that this is such a common task (I'd suppose). Is there actually a *simpler* way to achieve this? I've been looking for tutorials and how-to's on the web, but I really couldn't find any...


Any help is greatly appreciated!


Thanks,


Alan


Re: Merging conflicting models? [message #1171425 is a reply to message #1168809] Tue, 05 November 2013 08:12 Go to previous messageGo to next message
Laurent Goubet is currently offline Laurent GoubetFriend
Messages: 1639
Registered: July 2009
Senior Member
Hi Alan,

Quote:
The BatchMerger states in its Javadoc that it will merge *all* differences, regardless whether they are conflicting or not. What's the preferred way to merge all non-conflicting changes?


That is what the javadoc of the default constructor of the batch merger says. The javadoc of the other constructor answers your question with an example of code.

Since you are trying to merge everything, but with a little bit of logic for the conflicts, I'd say the easiest is probably to implement your own batch merger (Here I only give the code for the "left to right" part ... overriding the "right to left" one shouldn't be hard Smile) :

public void copyAllLeftToRight(Iterable<? extends Diff> differences, Monitor monitor) {
	for (Diff diff : Iterables.filter(differences, filter)) {
		if (diff.getState() != DifferenceState.MERGED) {
			copyLeftToRight(diff, monitor);
		}
	}
}

private void copyLeftToRight(Diff diff, Monitor monitor) {
	// The only diffs that need particular handling are the conflicting ones, less the pseudo-conflicts.
	final IMerger merger = registry.getHighestRankingMerger(diff);
	if (diff.getConflict() != null && diff.getConflict().getKind() != ConflictKind.PSEUDO) {
		handleConflictCopy(diff, merger, monitor);
	} else {
		merger.copyLeftToRight(diff, monitor);
	}
}

private void handleConflictCopy(Diff diff, IMerger merger, Monitor monitor) {
	MergeConflictResolution resolution = conflictResolver.resolve(conflict);
	switch (resolution) {
		case USE_MINE:
			merger.copyRightToLeft(diff, monitor);
			break;
		case USE_THEIRS:
			merger.copyLeftToRight(diff, monitor);
			break;
		default:
			throw new RuntimeException("Unknown MergeConflictResolution type: " + resolution);
	}
}


Then you only need to call this merger instead of the default "new BatchMerger(registry)" you were using.

Laurent Goubet
Obeo

[Updated on: Tue, 05 November 2013 08:12]

Report message to a moderator

Re: Merging conflicting models? [message #1176475 is a reply to message #1171425] Fri, 08 November 2013 10:59 Go to previous message
Alan DW is currently offline Alan DWFriend
Messages: 108
Registered: March 2012
Senior Member
Hi Laurent,

oh, then I must have overlooked that other constructor! I'll try to implement my own batch merger, it does not look *that* complicated at first glance, actually Smile

Thank you for your hints!


Alan
Previous Topic:EMF Compare - two equivalent updateReference seen as different
Next Topic:Potential Bug in ProximityEObjectMatcher
Goto Forum:
  


Current Time: Sun Dec 21 14:28:18 GMT 2014

Powered by FUDForum. Page generated in 0.01635 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software