changeset 90:a95c700408a9

Correctly report copy/rename events for rev..working copy case
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 26 Jan 2011 06:31:40 +0100
parents 42bcb4bffd17
children c2ce1cfaeb9e
files src/org/tmatesoft/hg/repo/StatusCollector.java src/org/tmatesoft/hg/repo/WorkingCopyStatusCollector.java
diffstat 2 files changed, 35 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/StatusCollector.java	Wed Jan 26 06:18:31 2011 +0100
+++ b/src/org/tmatesoft/hg/repo/StatusCollector.java	Wed Jan 26 06:31:40 2011 +0100
@@ -147,26 +147,10 @@
 					inspector.modified(fname);
 				}
 			} else {
-				HgDataFile df = repo.getFileNode(fname);
-				boolean isCopy = false;
-				while (df.isCopy()) {
-					Path original = df.getCopySourceName();
-					if (r1Files.contains(original.toString())) {
-						df = repo.getFileNode(original);
-						int changelogRevision = df.getChangesetLocalRevision(0);
-						if (changelogRevision <= rev1) {
-							// copy/rename source was known prior to rev1 
-							// (both r1Files.contains is true and original was created earlier than rev1)
-							// without r1Files.contains changelogRevision <= rev1 won't suffice as the file
-							// might get removed somewhere in between (changelogRevision < R < rev1)
-							inspector.copied(original.toString(), fname);
-							isCopy = true;
-						}
-						break;
-					} 
-					df = repo.getFileNode(original); // try more steps away
-				}
-				if (!isCopy) {
+				String copyOrigin = getOriginIfCopy(repo, fname, r1Files, rev1);
+				if (copyOrigin != null) {
+					inspector.copied(copyOrigin, fname);
+				} else {
 					inspector.added(fname);
 				}
 			}
@@ -182,6 +166,27 @@
 		walk(rev1, rev2, rv);
 		return rv;
 	}
+	
+	/*package-local*/static String getOriginIfCopy(HgRepository hgRepo, String fname, Collection<String> originals, int originalChangelogRevision) {
+		HgDataFile df = hgRepo.getFileNode(fname);
+		while (df.isCopy()) {
+			Path original = df.getCopySourceName();
+			if (originals.contains(original.toString())) {
+				df = hgRepo.getFileNode(original);
+				int changelogRevision = df.getChangesetLocalRevision(0);
+				if (changelogRevision <= originalChangelogRevision) {
+					// copy/rename source was known prior to rev1 
+					// (both r1Files.contains is true and original was created earlier than rev1)
+					// without r1Files.contains changelogRevision <= rev1 won't suffice as the file
+					// might get removed somewhere in between (changelogRevision < R < rev1)
+					return original.toString();
+				}
+				break; // copy/rename done later
+			} 
+			df = hgRepo.getFileNode(original); // try more steps away
+		}
+		return null;
+	}
 
 	public interface Inspector {
 		void modified(String fname);
--- a/src/org/tmatesoft/hg/repo/WorkingCopyStatusCollector.java	Wed Jan 26 06:18:31 2011 +0100
+++ b/src/org/tmatesoft/hg/repo/WorkingCopyStatusCollector.java	Wed Jan 26 06:31:40 2011 +0100
@@ -103,7 +103,7 @@
 			} else if (knownEntries.remove(fname)) {
 				// modified, added, removed, clean
 				if (collect != null) { // need to check against base revision, not FS file
-					checkLocalStatusAgainstBaseRevision(baseRevFiles, collect, fname, f, inspector);
+					checkLocalStatusAgainstBaseRevision(baseRevFiles, collect, baseRevision, fname, f, inspector);
 					baseRevFiles.remove(fname);
 				} else {
 					checkLocalStatusAgainstFile(fname, f, inspector);
@@ -165,7 +165,7 @@
 	}
 	
 	// XXX refactor checkLocalStatus methods in more OO way
-	private void checkLocalStatusAgainstBaseRevision(Set<String> baseRevNames, ManifestRevisionInspector collect, String fname, File f, StatusCollector.Inspector inspector) {
+	private void checkLocalStatusAgainstBaseRevision(Set<String> baseRevNames, ManifestRevisionInspector collect, int baseRevision, String fname, File f, StatusCollector.Inspector inspector) {
 		// fname is in the dirstate, either Normal, Added, Removed or Merged
 		Nodeid nid1 = collect.nodeid(fname);
 		String flags = collect.flags(fname);
@@ -174,9 +174,15 @@
 			// normal: added?
 			// added: not known at the time of baseRevision, shall report
 			// merged: was not known, report as added?
-			if ((r = getDirstate().checkAdded(fname)) != null) {
+			if ((r = getDirstate().checkNormal(fname)) != null) {
+				String origin = StatusCollector.getOriginIfCopy(repo, fname, baseRevNames, baseRevision);
+				if (origin != null) {
+					inspector.copied(origin, fname);
+					return;
+				}
+			} else if ((r = getDirstate().checkAdded(fname)) != null) {
 				if (r.name2 != null && baseRevNames.contains(r.name2)) {
-					baseRevNames.remove(r.name2);
+					baseRevNames.remove(r.name2); // XXX surely I shall not report rename source as Removed?
 					inspector.copied(r.name2, fname);
 					return;
 				}