Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [subversive-dev] Weird behavior of the "Compare with branch" feature

Hello,

After carefully analysing what will we get out of this functionality as it is, it seems it could not be implemented quite well yet. So, I suggest to simplify the code in this way:

1) We do compare the resources specified directly with 2-way comparision.
2) All the files that are changed locally would be marked as an outgoing changes
3) All other changes would be marked as an incoming changes.

The drawback of such solution is that we can't detect conflicting changes, still when the editor of the file is opened, we will be able to show where there are conflicts, incoming and outgoing changes.

I'm attaching the patch, so that you could try it and suggest any changes if you see the reason to do so. If you think it is all right as it is, then please let me know and I'll submit these changes to the repository.

Thank you in advance.

Best regards,
Alexander Gurov,
Subversive Team.

17.11.2015 17:11, fangebault+ml@xxxxxxxxxxxx пишет:
Le 04/11/2015 10:06, fangebault+ml@xxxxxxxxxxxx a écrit :
I wasn't aware of the three-way comparison stuff and I naively though
that it would just be a matter of re-implementing methods
SVNUtility#diffStatus().
I'm not familiar with subversive's API but I'll give it a try.
OK now I know it's not that simple. Can you suggest me a quick-and-dirty
fix that would not handle three-way comparison?
I would like to provide our customer with a temporary fix so that at
least he would not be misleaded by this feature.



--
Best regards,
Alexander Gurov,
Subversive Team.

Index: src/org/eclipse/team/svn/ui/operation/CompareResourcesInternalOperation.java
===================================================================
--- src/org/eclipse/team/svn/ui/operation/CompareResourcesInternalOperation.java	(revision 21500)
+++ src/org/eclipse/team/svn/ui/operation/CompareResourcesInternalOperation.java	(working copy)
@@ -18,30 +18,29 @@
 import org.eclipse.compare.CompareEditorInput;
 import org.eclipse.compare.internal.CompareEditor;
 import org.eclipse.compare.internal.Utilities;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.swt.widgets.Shell;
-import org.eclipse.team.svn.core.SVNMessages;
+import org.eclipse.team.svn.core.IStateFilter;
 import org.eclipse.team.svn.core.connector.ISVNConnector;
-import org.eclipse.team.svn.core.connector.ISVNEntryStatusCallback;
-import org.eclipse.team.svn.core.connector.SVNChangeStatus;
+import org.eclipse.team.svn.core.connector.ISVNDiffStatusCallback;
 import org.eclipse.team.svn.core.connector.SVNDepth;
 import org.eclipse.team.svn.core.connector.SVNDiffStatus;
+import org.eclipse.team.svn.core.connector.SVNEntry;
 import org.eclipse.team.svn.core.connector.SVNEntryRevisionReference;
 import org.eclipse.team.svn.core.connector.SVNRevision;
-import org.eclipse.team.svn.core.connector.SVNRevision.Kind;
-import org.eclipse.team.svn.core.connector.SVNRevisionRange;
 import org.eclipse.team.svn.core.operation.AbstractActionOperation;
-import org.eclipse.team.svn.core.operation.IActionOperation;
 import org.eclipse.team.svn.core.operation.IUnprotectedOperation;
 import org.eclipse.team.svn.core.operation.SVNProgressMonitor;
-import org.eclipse.team.svn.core.operation.remote.LocateResourceURLInHistoryOperation;
 import org.eclipse.team.svn.core.resource.ILocalResource;
 import org.eclipse.team.svn.core.resource.IRepositoryLocation;
 import org.eclipse.team.svn.core.resource.IRepositoryResource;
 import org.eclipse.team.svn.core.svnstorage.SVNRemoteStorage;
 import org.eclipse.team.svn.core.utility.FileUtility;
-import org.eclipse.team.svn.core.utility.ProgressMonitorUtility;
 import org.eclipse.team.svn.core.utility.SVNUtility;
 import org.eclipse.team.svn.ui.SVNTeamUIPlugin;
 import org.eclipse.team.svn.ui.SVNUIMessages;
@@ -91,98 +90,67 @@
 	}
 	
 	protected void runImpl(final IProgressMonitor monitor) throws Exception {
-		/*
-		 * As there's no svn operation (svn diff) which can compare working copy url and repository url
-		 * which doesn't match to working copy url (e.g. compare working copy with another branch etc.)
-		 * we need extra handling: and so we calculate local changes (using svn status)
-		 * and remote changes (using svn diff).
-		 * In order to compare working copy and not matched to it repository url we detect repository
-		 * url corresponding to working copy and compare it with repository url, in other words,
-		 * we compare 2 repository urls.
-		 */		
 		final ArrayList<SVNDiffStatus> localChanges = new ArrayList<SVNDiffStatus>();
 		final ArrayList<SVNDiffStatus> remoteChanges = new ArrayList<SVNDiffStatus>();
 		
 		final IRepositoryLocation location = SVNRemoteStorage.instance().getRepositoryLocation(this.local.getResource());
 		final ISVNConnector proxy = location.acquireSVNProxy();
 		
-		final IRepositoryResource []diffPair = new IRepositoryResource[] {this.ancestor, this.remote};
-		SVNRevision revision = this.remote.getSelectedRevision();
-		boolean fetchRemote = revision.getKind() == Kind.HEAD || revision.getKind() == Kind.NUMBER;
-		
+		final IProject project = this.local.getResource().getProject();
+		final IPath rootPath = FileUtility.getResourcePath(project);
+
 		this.protectStep(new IUnprotectedOperation() {
 			public void run(IProgressMonitor monitor) throws Exception {
-				proxy.status(FileUtility.getWorkingCopyPath(CompareResourcesInternalOperation.this.local.getResource()), SVNDepth.INFINITY, ISVNConnector.Options.IGNORE_EXTERNALS, null, new ISVNEntryStatusCallback() {
-					public void next(SVNChangeStatus status) {
-						localChanges.add(new SVNDiffStatus(status.path, status.path, status.nodeKind, status.textStatus, status.propStatus));
+				SVNEntryRevisionReference refPrev = new SVNEntryRevisionReference(FileUtility.getWorkingCopyPath(CompareResourcesInternalOperation.this.local.getResource()), null, SVNRevision.WORKING);
+				final SVNEntryRevisionReference refNext = SVNUtility.getEntryRevisionReference(CompareResourcesInternalOperation.this.remote);
+				proxy.diffStatusTwo(refPrev, refNext, SVNDepth.INFINITY, ISVNConnector.Options.NONE, null, new ISVNDiffStatusCallback() {
+					public void next(SVNDiffStatus status) {
+						IPath tPath = new Path(status.pathPrev);
+						tPath = tPath.removeFirstSegments(rootPath.segmentCount());
+						IResource resource = project.findMember(tPath);
+						if (resource == null) {
+							resource = status.nodeKind == SVNEntry.Kind.FILE ? project.getFile(tPath) : project.getFolder(tPath);
+						}
+						if (IStateFilter.SF_ANY_CHANGE.accept(SVNRemoteStorage.instance().asLocalResource(resource))) {
+							localChanges.add(status);
+						}
+						else {
+							String pathPrev = CompareResourcesInternalOperation.this.ancestor.getUrl() + status.pathNext.substring(refNext.path.length());
+							remoteChanges.add(new SVNDiffStatus(pathPrev, status.pathNext, status.nodeKind, status.textStatus, status.propStatus));
+						}
 					}
 				}, new SVNProgressMonitor(CompareResourcesInternalOperation.this, monitor, null, false));
 			}
-		}, monitor, 100, fetchRemote ? 5 : 60);
-		
-		if (!monitor.isCanceled() && fetchRemote && !SVNRevision.INVALID_REVISION.equals(this.ancestor.getSelectedRevision()) && !SVNRevision.INVALID_REVISION.equals(this.remote.getSelectedRevision())) {
-			this.protectStep(new IUnprotectedOperation() {
-				public void run(IProgressMonitor monitor) throws Exception {
-					LocateResourceURLInHistoryOperation op = new LocateResourceURLInHistoryOperation(diffPair);
-					ProgressMonitorUtility.doTaskExternal(op, monitor);
-					if (op.getExecutionState() != IActionOperation.OK) {
-						CompareResourcesInternalOperation.this.reportStatus(op.getStatus());
-						return;
-					}
-					diffPair[0] = op.getRepositoryResources()[0];
-					diffPair[1] = op.getRepositoryResources()[1];
-				}
-			}, monitor, 100, 55);
-			if (this.getExecutionState() == IActionOperation.ERROR) {
-				return;
-			}
-			this.protectStep(new IUnprotectedOperation() {
-				public void run(IProgressMonitor monitor) throws Exception {
-					ProgressMonitorUtility.setTaskInfo(monitor, CompareResourcesInternalOperation.this, SVNMessages.Progress_Running);
-					
-					SVNEntryRevisionReference refPrev = SVNUtility.getEntryRevisionReference(diffPair[0]);
-					SVNEntryRevisionReference refNext = SVNUtility.getEntryRevisionReference(diffPair[1]);
-					if (SVNUtility.useSingleReferenceSignature(refPrev, refNext)) {
-						SVNUtility.diffStatus(proxy, remoteChanges, refPrev, new SVNRevisionRange(refPrev.revision, refNext.revision), SVNDepth.INFINITY, ISVNConnector.Options.NONE, new SVNProgressMonitor(CompareResourcesInternalOperation.this, monitor, null, false));
-					}
-					else {
-						SVNUtility.diffStatus(proxy, remoteChanges, refPrev, refNext, SVNDepth.INFINITY, ISVNConnector.Options.NONE, new SVNProgressMonitor(CompareResourcesInternalOperation.this, monitor, null, false));
-					}
-				}
-			}, monitor, 100, 5);
-		}
+		}, monitor, 100, 50);
 		
 		location.releaseSVNProxy(proxy);
 		
-		if (!monitor.isCanceled()) {
-			this.protectStep(new IUnprotectedOperation() {
-				public void run(IProgressMonitor monitor) throws Exception {
-					CompareConfiguration cc = new CompareConfiguration();
-					cc.setProperty(CompareEditor.CONFIRM_SAVE_PROPERTY, Boolean.TRUE);
-					diffPair[0].setSelectedRevision(SVNRevision.BASE);
-					final ThreeWayResourceCompareInput compare = new ThreeWayResourceCompareInput(cc, CompareResourcesInternalOperation.this.local, diffPair[0], diffPair[1], localChanges, remoteChanges);
-					compare.setForceId(CompareResourcesInternalOperation.this.forceId);
-					compare.initialize(monitor);
-					if (!monitor.isCanceled())
-					{
-						UIMonitorUtility.getDisplay().syncExec(new Runnable() {
-							public void run() {
-								if (CompareResourcesInternalOperation.this.showInDialog) {
-									if (CompareResourcesInternalOperation.this.compareResultOK(compare)) {
-										ComparePanel panel = new ComparePanel(compare, CompareResourcesInternalOperation.this.local.getResource());
-										DefaultDialog dialog = new DefaultDialog(UIMonitorUtility.getShell(), panel);
-										dialog.open();
-									}
-								}
-								else {
-									ResourceCompareInput.openCompareEditor(compare, CompareResourcesInternalOperation.this.forceReuse);
+		this.protectStep(new IUnprotectedOperation() {
+			public void run(IProgressMonitor monitor) throws Exception {
+				CompareConfiguration cc = new CompareConfiguration();
+				cc.setProperty(CompareEditor.CONFIRM_SAVE_PROPERTY, Boolean.TRUE);
+				final ThreeWayResourceCompareInput compare = new ThreeWayResourceCompareInput(cc, CompareResourcesInternalOperation.this.local, CompareResourcesInternalOperation.this.ancestor, CompareResourcesInternalOperation.this.remote, localChanges, remoteChanges);
+				compare.setForceId(CompareResourcesInternalOperation.this.forceId);
+				compare.initialize(monitor);
+				if (!monitor.isCanceled())
+				{
+					UIMonitorUtility.getDisplay().syncExec(new Runnable() {
+						public void run() {
+							if (CompareResourcesInternalOperation.this.showInDialog) {
+								if (CompareResourcesInternalOperation.this.compareResultOK(compare)) {
+									ComparePanel panel = new ComparePanel(compare, CompareResourcesInternalOperation.this.local.getResource());
+									DefaultDialog dialog = new DefaultDialog(UIMonitorUtility.getShell(), panel);
+									dialog.open();
 								}
 							}
-						});
-					}
+							else {
+								ResourceCompareInput.openCompareEditor(compare, CompareResourcesInternalOperation.this.forceReuse);
+							}
+						}
+					});
 				}
-			}, monitor, 100, 40);
-		}
+			}
+		}, monitor, 100, 50);
 	}
 	
 	protected boolean compareResultOK(CompareEditorInput input) {

Back to the top