Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [subversive-dev] New problems when using "Compare with branch..."

Le 04/11/2016 à 09:10, Florent Angebault a écrit :
> Le 02/11/2016 à 14:25, Alexander Gurov a écrit :
>>> - SameContent.java is shown as an incoming deletion while it should not
>>>   shown at all because there is no difference (this is bug [326694]
>>>   but this time without common ancestry)
>>> - DifferentContent.java is shown as an incoming deletion while it
>>>   should be shown as an incoming change or a conflict


I did many tests to find out how to remove false positive (files with no
differences). It seems that the available API do not provide a simple
way to discard files with same content. The only solution I could find
is to actually perform a real diff (with ISVNConnector#diffTwo()) and
parse the output to catch the names of files that are really different.

Here is the (dirty) patch that solves both problems mentionned above.


-- 
Florent Angebault
Linagora - Support OSSA
https://www.08000linux.com/
diff --git a/org.eclipse.team.svn.ui/src/org/eclipse/team/svn/ui/operation/CompareResourcesInternalOperation.java b/org.eclipse.team.svn.ui/src/org/eclipse/team/svn/ui/operation/CompareResourcesInternalOperation.java
index a61cba5..3ce1599 100644
--- a/org.eclipse.team.svn.ui/src/org/eclipse/team/svn/ui/operation/CompareResourcesInternalOperation.java
+++ b/org.eclipse.team.svn.ui/src/org/eclipse/team/svn/ui/operation/CompareResourcesInternalOperation.java
@@ -11,10 +11,13 @@
 
 package org.eclipse.team.svn.ui.operation;
 
+import java.io.IOException;
+import java.io.OutputStream;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
+import java.util.Set;
 
 import org.eclipse.compare.CompareConfiguration;
 import org.eclipse.compare.CompareEditorInput;
@@ -255,7 +258,9 @@ public class CompareResourcesInternalOperation extends AbstractActionOperation {
 				SVNEntryRevisionReference refPrev = new SVNEntryRevisionReference(FileUtility.getWorkingCopyPath(CompareResourcesInternalOperation.this.local.getResource()), null, SVNRevision.WORKING);
 				final SVNEntryRevisionReference refNext = SVNUtility.getEntryRevisionReference(CompareResourcesInternalOperation.this.remote);
 				// does not work with BASE working copy revision (not implemented yet exception)
-				proxy.diffStatusTwo(refPrev, refNext, SVNDepth.INFINITY, ISVNConnector.Options.NONE, null, new ISVNDiffStatusCallback() {
+				final FakeOutputStream diffPathCollector = new FakeOutputStream();
+				proxy.diffTwo(refPrev, refNext, rootPath.toFile().getAbsolutePath(), diffPathCollector, SVNDepth.INFINITY, ISVNConnector.Options.IGNORE_ANCESTRY, null, ISVNConnector.DiffOptions.IGNORE_WHITESPACE, new SVNProgressMonitor(CompareResourcesInternalOperation.this, monitor, null, false));
+				proxy.diffStatusTwo(refPrev, refNext, SVNDepth.INFINITY, ISVNConnector.Options.IGNORE_ANCESTRY, null, new ISVNDiffStatusCallback() {
 					public void next(SVNDiffStatus status) {
 						IPath tPath = new Path(status.pathPrev);
 						tPath = tPath.removeFirstSegments(rootPath.segmentCount());
@@ -272,15 +277,66 @@ public class CompareResourcesInternalOperation extends AbstractActionOperation {
 								(status.textStatus == SVNDiffStatus.Kind.DELETED ? SVNDiffStatus.Kind.ADDED : status.textStatus);
 							// TODO could there be a case when relative paths are reported? If so - looks like a bug to me...
 							String pathPrev = status.pathNext.startsWith(refNext.path) ? status.pathNext.substring(refNext.path.length()) : status.pathNext;
-							pathPrev = CompareResourcesInternalOperation.this.ancestor.getUrl() + pathPrev;
-							remoteChanges.add(new SVNDiffStatus(pathPrev, status.pathNext, status.nodeKind, change, status.propStatus));
+							if (!diffPathCollector.contains(pathPrev)) {
+								System.out.println("ignoring path: " + pathPrev);
+							} else {
+								pathPrev = CompareResourcesInternalOperation.this.ancestor.getUrl() + pathPrev;
+								remoteChanges.add(new SVNDiffStatus(pathPrev, status.pathNext, status.nodeKind, change, status.propStatus));
+							}
 						}
 					}
 				}, new SVNProgressMonitor(CompareResourcesInternalOperation.this, monitor, null, false));
 			}
 		}, monitor, 100, 40);
 	}
+
+	/**
+	 * Workaround.
+	 * 
+	 * This {@link OutputStream} parses the output of "svn diff" and only catches paths from
+	 * the lines beginning with "Index: ".
+	 * 
+	 * @author fangebault
+	 */
+	private static class FakeOutputStream extends OutputStream {
+
+		boolean lineStart = true;
+		boolean indexLine = false;
+		Set<String> paths = new LinkedHashSet<String>();
+		StringBuilder w = new StringBuilder();
+		
+		@Override
+		public void write(int b) throws IOException {
+			char c = (char) b;
+			System.out.print(c);
+			if (c == 'I' && this.lineStart) {
+				this.indexLine = true;
+				this.w.append(c);
+			} else if (c == '\n' || c == '\r') {
+				if (this.indexLine) {
+					this.paths.add("/" + this.w.toString().substring("Index: ".length()));
+					this.w.replace(0, this.w.length(), "");
+				}
+				this.lineStart = true;
+				this.indexLine = false;
+			} else {
+				this.lineStart = false;
+				if (this.indexLine) {
+					this.w.append(c);
+				}
+			}
+		}
+		
+		private Set<String> getPaths() {
+			return this.paths;
+		}
+		
+		public boolean contains(String path) {
+			return this.getPaths().contains(path);
+		}
 	
+	}
+
 	protected boolean compareResultOK(CompareEditorInput input) {
 		final Shell shell = UIMonitorUtility.getShell();
 		

Back to the top