# HG changeset patch # User Artem Tikhomirov # Date 1296019900 -3600 # Node ID a95c700408a906cf98e2c7742f00272f5f848155 # Parent 42bcb4bffd17be14a054e12522730d56a2301d1c Correctly report copy/rename events for rev..working copy case diff -r 42bcb4bffd17 -r a95c700408a9 src/org/tmatesoft/hg/repo/StatusCollector.java --- 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 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); diff -r 42bcb4bffd17 -r a95c700408a9 src/org/tmatesoft/hg/repo/WorkingCopyStatusCollector.java --- 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 baseRevNames, ManifestRevisionInspector collect, String fname, File f, StatusCollector.Inspector inspector) { + private void checkLocalStatusAgainstBaseRevision(Set 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; }