Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Daussy2018-06-01 12:19:46 +0000
committerLaurent Goubet2018-06-04 13:09:00 +0000
commitf532d524682a7fb3c8c1b52483dd6ed52ca5708b (patch)
tree27afda125461d023a46de57b5d527fe6f4cc5afb /plugins
parent1661e48676deb3a23e2f55275b2a6610923a6643 (diff)
downloadorg.eclipse.emf.compare-f532d524682a7fb3c8c1b52483dd6ed52ca5708b.tar.gz
org.eclipse.emf.compare-f532d524682a7fb3c8c1b52483dd6ed52ca5708b.tar.xz
org.eclipse.emf.compare-f532d524682a7fb3c8c1b52483dd6ed52ca5708b.zip
Do not handle "merged" files twice when JGit stages them
In some cases, JGit will stage the files that are "in-sync" directly when walking over them instead of leaving this decision to the merger. In such cases, EMF Compare's handling of files through the logical model merging creates duplicate entries in the DirCache for stage 0. Bug: 535200 Change-Id: I66e62cef3425289e384a02dcdcc8a2c1349d0400
Diffstat (limited to 'plugins')
-rw-r--r--plugins/org.eclipse.emf.compare.egit/src/org/eclipse/emf/compare/egit/internal/merge/RecursiveModelMerger.java28
1 files changed, 23 insertions, 5 deletions
diff --git a/plugins/org.eclipse.emf.compare.egit/src/org/eclipse/emf/compare/egit/internal/merge/RecursiveModelMerger.java b/plugins/org.eclipse.emf.compare.egit/src/org/eclipse/emf/compare/egit/internal/merge/RecursiveModelMerger.java
index 46d5ff2ca..5c28d7dec 100644
--- a/plugins/org.eclipse.emf.compare.egit/src/org/eclipse/emf/compare/egit/internal/merge/RecursiveModelMerger.java
+++ b/plugins/org.eclipse.emf.compare.egit/src/org/eclipse/emf/compare/egit/internal/merge/RecursiveModelMerger.java
@@ -59,6 +59,7 @@ import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.WorkingTreeIterator;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.diff.IDiff;
@@ -175,6 +176,18 @@ public class RecursiveModelMerger extends RecursiveMerger {
throw new OperationCanceledException();
}
+ // The treewalk might decide to handle files with no differences by itself instead of leaving that
+ // decision to us (id treewalk.getFilter() is "AnyDiff", then it'll skip over the "in-sync" files
+ // while adding them to the dircache at the same time). In such a case, we need to prevent ModelMerge
+ // from adding the "unchanged" files (which require no merging) in the DirCacheBuilder, otherwise
+ // we'll end up with "duplicate stage not allowed" exceptions at the end of merge operations
+ // (dirCache.finish()).
+ // see also bug #535200
+ boolean handleUnchangedFiles = true;
+ if (treeWalk.getFilter() == TreeFilter.ANY_DIFF) {
+ handleUnchangedFiles = false;
+ }
+
// We are done with the setup. We can now iterate over the tree walk and
// either delegate to the logical model's merger if any or fall back to
// standard git merging. Basically, any file that is not a part of a
@@ -233,7 +246,7 @@ public class RecursiveModelMerger extends RecursiveMerger {
enterSubtree = true;
boolean success = new ModelMerge(this, subscriber, remoteMappingContext, path, logicalModel,
- modelMerger).run(new JGitProgressMonitorWrapper(monitor));
+ modelMerger, handleUnchangedFiles).run(new JGitProgressMonitorWrapper(monitor));
if (!success) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("FAILED - Recursive model merge."); //$NON-NLS-1$
@@ -401,15 +414,18 @@ public class RecursiveModelMerger extends RecursiveMerger {
private final IResourceMappingMerger modelMerger;
+ private final boolean handleUnchangedFiles;
+
public ModelMerge(RecursiveModelMerger merger, GitResourceVariantTreeSubscriber subscriber,
RemoteResourceMappingContext remoteMappingContext, String path, Set<IResource> logicalModel,
- IResourceMappingMerger modelMerger) {
+ IResourceMappingMerger modelMerger, boolean handleUnchangedFiles) {
this.merger = merger;
this.subscriber = subscriber;
this.remoteMappingContext = remoteMappingContext;
this.path = path;
this.logicalModel = logicalModel;
this.modelMerger = modelMerger;
+ this.handleUnchangedFiles = handleUnchangedFiles;
}
private boolean run(IProgressMonitor monitor) throws CorruptObjectException, IOException {
@@ -488,9 +504,11 @@ public class RecursiveModelMerger extends RecursiveMerger {
if (mergeContext.getDiffTree().getDiff(handledFile) == null) {
// If no diff, the model merger does... nothing
// Make sure this file will be added to the index.
- merger.registerMergedPath(filePath);
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Merged non-modified file: " + filePath); //$NON-NLS-1$
+ if (handleUnchangedFiles) {
+ merger.registerMergedPath(filePath);
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Merged non-modified file: " + filePath); //$NON-NLS-1$
+ }
}
} else if (filePath != null && status.getSeverity() != IStatus.OK) {
if (merger.makeInSync.contains(filePath)) {

Back to the top