Mercurial > jhg
diff src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java @ 280:35125450c804
Erroneous and slow status for working copies based on non-tip revision
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 02 Sep 2011 13:40:09 +0200 |
parents | 6d1804fe0ed7 |
children | e51dd9a14b6f |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java Wed Aug 31 23:22:18 2011 +0200 +++ b/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java Fri Sep 02 13:40:09 2011 +0200 @@ -59,7 +59,6 @@ private HgDirstate dirstate; private HgStatusCollector baseRevisionCollector; private PathPool pathPool; - private ManifestRevision dirstateParentManifest; public HgWorkingCopyStatusCollector(HgRepository hgRepo) { this(hgRepo, new HgInternals(hgRepo).createWorkingDirWalker(null)); @@ -145,7 +144,7 @@ final PathPool pp = getPathPool(); while (repoWalker.hasNext()) { repoWalker.next(); - Path fname = pp.path(repoWalker.name()); + final Path fname = pp.path(repoWalker.name()); File f = repoWalker.file(); if (!f.exists()) { // file coming from iterator doesn't exist. @@ -237,9 +236,13 @@ HgDirstate.Record r; if ((r = getDirstate().checkNormal(fname)) != null) { // either clean or modified - if (f.lastModified() / 1000 == r.time && r.size == f.length()) { - inspector.clean(getPathPool().path(fname)); + final boolean timestampEqual = getFileModificationTime(f) == r.time, sizeEqual = r.size == f.length(); + if (timestampEqual && sizeEqual) { + inspector.clean(fname); + } else if (!sizeEqual && r.size >= 0) { + inspector.modified(fname); } else { + // size is the same or unknown, and, perhaps, different timestamp // check actual content to avoid false modified files HgDataFile df = repo.getFileNode(fname); if (!areTheSame(f, df, HgRepository.TIP)) { @@ -250,17 +253,22 @@ } } else if ((r = getDirstate().checkAdded(fname)) != null) { if (r.name2 == null) { - inspector.added(getPathPool().path(fname)); + inspector.added(fname); } else { - inspector.copied(getPathPool().path(r.name2), getPathPool().path(fname)); + inspector.copied(getPathPool().path(r.name2), fname); } } else if ((r = getDirstate().checkRemoved(fname)) != null) { - inspector.removed(getPathPool().path(fname)); + inspector.removed(fname); } else if ((r = getDirstate().checkMerged(fname)) != null) { - inspector.modified(getPathPool().path(fname)); + inspector.modified(fname); } } + // return mtime analog, directly comparable to dirstate's mtime. + private static int getFileModificationTime(File f) { + return (int) (f.lastModified() / 1000); + } + // XXX refactor checkLocalStatus methods in more OO way private void checkLocalStatusAgainstBaseRevision(Set<String> baseRevNames, ManifestRevision collect, int baseRevision, Path fname, File f, HgStatusInspector inspector) { // fname is in the dirstate, either Normal, Added, Removed or Merged @@ -296,23 +304,28 @@ inspector.added(fname); } else { // was known; check whether clean or modified - // when added - seems to be the case of a file added once again, hence need to check if content is different - if ((r = getDirstate().checkNormal(fname)) != null || (r = getDirstate().checkMerged(fname)) != null || (r = getDirstate().checkAdded(fname)) != null) { + if ((r = getDirstate().checkNormal(fname)) != null) { + final boolean timestampEqual = getFileModificationTime(f) == r.time, sizeEqual = r.size == f.length(); + if (timestampEqual && sizeEqual) { + inspector.clean(fname); + baseRevNames.remove(fname.toString()); // consumed, processed, handled. + return; + } else if (!sizeEqual && r.size >= 0) { + inspector.modified(fname); + baseRevNames.remove(fname.toString()); // consumed, processed, handled. + return; + } + // otherwise, shall check actual content (size not the same, or unknown (-1 or -2), or timestamp is different) + // FALL THROUGH + } + if (r != null /*Normal dirstate, but needs extra check*/ || (r = getDirstate().checkMerged(fname)) != null || (r = getDirstate().checkAdded(fname)) != null) { + // when added - seems to be the case of a file added once again, hence need to check if content is different // either clean or modified - HgDataFile fileNode = repo.getFileNode(fname); - int lengthAtRevision; - try { - lengthAtRevision = fileNode.length(nid1); - } catch (HgDataStreamException ex) { - ex.printStackTrace(); // XXX log error - lengthAtRevision = -1; // compare file content then - } - // XXX is it safe with respect to filters (keyword, eol) to compare lengthAtRevision (unprocessed) with size - // from dirstate, which I assume is size of processed data? - if (r.size != -1 && r.size /* XXX File.length() ?! */ != lengthAtRevision || flags != todoGenerateFlags(fname /*java.io.File*/)) { + if (r.size != -1 /*XXX what about ==-2?*/&& r.size != f.length() || !todoCheckFlagsEqual(f, flags)) { inspector.modified(fname); } else { // check actual content to see actual changes + HgDataFile fileNode = repo.getFileNode(fname); if (areTheSame(f, fileNode, fileNode.getLocalRevision(nid1))) { inspector.clean(fname); } else { @@ -412,9 +425,9 @@ return false; } - private static String todoGenerateFlags(Path fname) { + private static boolean todoCheckFlagsEqual(File f, String manifestFlags) { // FIXME implement - return null; + return true; } /**