Hi Laurent,
I've decided to do the normal 3-way comparison and validate the
resulting model (don't know how, yet) afterwards.
However I got some problems. The isConflicting() method always returns
false.
I've changed the same property to different values in File2&3, or
changed it to a value in one File and deleted it in the other File.
Always false.
My other problem is, that I can't get the merge to work.
if I use : MergeService.merge( differences, true ); i get:
java.util.ConcurrentModificationException
at
org.eclipse.emf.common.util.BasicEList$EIterator.checkModCount(BasicEList.java:1378)
at
org.eclipse.emf.common.util.BasicEList$EIterator.doNext(BasicEList.java:1332)
at
org.eclipse.emf.common.util.BasicEList$EIterator.next(BasicEList.java:1312)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.merge(MergeService.java:132)
and if i change it to: MergeService.merge( differences, false ); i get:
java.lang.NullPointerException
at
org.eclipse.emf.compare.util.EFactory.eStructuralFeature(EFactory.java:216)
at org.eclipse.emf.compare.util.EFactory.eAdd(EFactory.java:58)
at
org.eclipse.emf.compare.diff.internal.merge.impl.MoveModelElementMerger.applyInOrigin(MoveModelElementMerger.java:44)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.doMerge(MergeService.java:174)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.merge(MergeService.java:136)
at
org.eclipse.emf.compare.diff.internal.merge.impl.DiffGroupMerger.applyInOrigin(DiffGroupMerger.java:35)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.doMerge(MergeService.java:174)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.merge(MergeService.java:136)
at
org.eclipse.emf.compare.diff.internal.merge.impl.DiffGroupMerger.applyInOrigin(DiffGroupMerger.java:35)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.doMerge(MergeService.java:174)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.merge(MergeService.java:136)
at
org.eclipse.emf.compare.diff.internal.merge.impl.DiffGroupMerger.applyInOrigin(DiffGroupMerger.java:35)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.doMerge(MergeService.java:174)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.merge(MergeService.java:136)
at
org.eclipse.emf.compare.diff.internal.merge.impl.DiffGroupMerger.applyInOrigin(DiffGroupMerger.java:35)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.doMerge(MergeService.java:174)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.merge(MergeService.java:136)
at
org.eclipse.emf.compare.diff.internal.merge.impl.DiffGroupMerger.applyInOrigin(DiffGroupMerger.java:35)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.doMerge(MergeService.java:174)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.merge(MergeService.java:136)
at
org.eclipse.emf.compare.diff.internal.merge.impl.DiffGroupMerger.applyInOrigin(DiffGroupMerger.java:35)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.doMerge(MergeService.java:174)
at
org.eclipse.emf.compare.diff.merge.service.MergeService.merge(MergeService.java:136)
Do you have any advice or suggestions?
Thanks a lot.
Daniel
laurent Goubet wrote:
Hi Daniel,
3-way matching doesn't seem to be what you seek. As you mentionned,
you want to compare File1 with File2, File1 with File3 _and_ File2
with File3... and execute some logic with the results of these
comparisons, ignoring part of the changes, resolving conflicts, and
merging part of the others. Well the logic here clearly is more
important than a standard 3-way diff.
You might be able to create a mix of changes with 2-way diffing 1 and
2, then 1 and 3 and a 3-way differencing to detect conflicts ... but I
think you should clearly determine the needed logic beforehand :p.
Laurent Goubet
Obeo
Daniel a écrit :
Hi Laurent,
Thanks for your fast answer. I upgraded to 1.0 and finally saw the
methods and classes you were talking about. ;-)
The thing with the many movings also dissapeared, seems like a fixed
bug. So I also don't have to do the instance of
"ReferenceOrderChange" check.
Still my problem is, that I need to know the origin File of a change,
even if it is not conflicting. This is because the resulting file has
to be conform to the new base, only enhanced with the customizings
but there is logic, which has to be checked before i can add it (even
if nonconflicting)otherwise the model could be unusable.
If I check on isRemote() in the 3wayDiff I get a false for every
(nonconflicting) DiffElement in the Diff.
So I assume that a 3 way Diff has only the informations of the
ancestor on one side and a nonconflicting mixture of the changes from
the 2 customized childfiles on the other side, however without
reference from which file the changes came from.
If it is not possible to get the origin file of a change I have to
use another approach and do two 2way diffs, than somehow compare the
diffs and delete the ones I don't like. Is there some unique id with
which i can compare the DiffElements of two Diffs? (Maybe i'll do a
Diff of File 2 and 3 and then subtract the Diff of File 1 and 3 from
it.)
Cheers
Daniel
laurent Goubet wrote:
Hi Daniel,
Comments inlined below.
Daniel a écrit :
Hi,
Thank you for your work and effort.
My situation is the following: I have 3 Model instances,
File 1: a base, File 2: a base file with some customisations
File 3: and another customized (further developed) base file, say
new base.
I want to get the customisations of File 2 into file 3. Therefore i
have to solve some conflicts between those files.
Firstly I want to make sure that this is the right approach for the
3way match.
I use the ressourceMatch() Method with the 3 Files, than created a
Diff out of it.
conflict detection/resolution can only be made when comparing two
files along with their common ancestor. Thus you can indeed use
three-way differencing and hope to have interesting results if both
your "file3" and "file2" are derived from the same base "file1".
MatchService.doResourceMatch() followed by DiffService.doDiff(match)
is indeed the way to get the differences.
1 Question: How do I ignore changes which only affect the order of
the elements? (...has been moved from ... to)
We've never implemented a way to ignore differences when comparing,
but you can do it programmatically when merging by not merging all
DiffElements instance of "ReferenceOrderChange".
2 Question: I get an Diff out of the 3way Matchmodel, but how do i
get the origin file of a DiffElement? So how do I know if the
change was between file 1 and 2 or 1 and 3?
MatchService.doResourceMatch takes 3 resources as parameter : left,
right and ancestor (in this order). Talking in terms of version
control system, "left" is your "local" resource (File3), "right" is
the remote file (on repository) (File2) and "ancestor" is, well, the
common ancestor of both files (File1).
With 3-way changes, we'll see "remote" changes and "normal" changes.
Namely, if you have a Class "Class1" in File1, File2 has renamed
this class "Class2" and File3 sports a change in which the class is
renamed "Class3", we'll detect a conflicting change. In the
DiffModel, this means we'll have a "ConflictingDiffElement"
containing an "AttributeChange" for the change to "Class3" and a
remote "AttributeChange" (which method "isRemote() returns true) for
the change to "Class2".
In opposition, if your File2 had changed the name of your class to
"Class" and File3 has done the same, no difference would have even
been detected even though File1 had this class named "Class1".
You can know whether the change had been made in File2 if it is
marked as a "remote" change.
3 Question: I've found a graphic with a "diff extensions" api
marked. But where and how do I use this api, and can I use it to
manually solve the conflicts with it?
The diff extension API can be used to change the DiffModel itself by
regrouping differencesin order to "hide" them between a higher
difference. This doesn't seem to be what you seek.
If you want to merge differences, use the MergeService API (similar
to MatchService and DiffService, this allows you to merge
differences easily given the DiffModel). Conflict resolution is only
a matter of merging the conflicting difference from left to right or
right to left (in my exemple above, File3 to File2 or File2 to File3
respectively).
We might need to implement a "smarter" conflict resolution API, but
for now that's what you can access :).
Thank you in advance,
greetings
Daniel
Cheers,
Laurent Goubet
Obeo