Mercurial > jhg
diff src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java @ 275:6d1804fe0ed7
Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 25 Aug 2011 21:35:03 +0200 |
parents | 3fbfce107f94 |
children | 35125450c804 |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java Thu Aug 25 03:57:39 2011 +0200 +++ b/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java Thu Aug 25 21:35:03 2011 +0200 @@ -59,6 +59,7 @@ private HgDirstate dirstate; private HgStatusCollector baseRevisionCollector; private PathPool pathPool; + private ManifestRevision dirstateParentManifest; public HgWorkingCopyStatusCollector(HgRepository hgRepo) { this(hgRepo, new HgInternals(hgRepo).createWorkingDirWalker(null)); @@ -100,21 +101,31 @@ } return dirstate; } - + // may be invoked few times + // NOTE, use of TIP constant requires certain care. TIP here doesn't mean latest cset, but actual working copy parent. + // XXX this shall be changed, though, and use of TIP throughout code shall be revised - + // consider case when repository is updated to one of its previous revisions. TIP points to last change, but a lot of + // commands need to work with revision that is in dirstate now. public void walk(int baseRevision, HgStatusInspector inspector) { if (HgInternals.wrongLocalRevision(baseRevision) || baseRevision == BAD_REVISION || baseRevision == WORKING_COPY) { throw new IllegalArgumentException(String.valueOf(baseRevision)); } final HgIgnore hgIgnore = repo.getIgnore(); TreeSet<String> knownEntries = getDirstate().all(); - final boolean isTipBase; if (baseRevision == TIP) { - baseRevision = repo.getChangelog().getLastRevision(); - isTipBase = true; - } else { - isTipBase = baseRevision == repo.getChangelog().getLastRevision(); + // WC not necessarily points to TIP, but may be result of update to any previous revision. + // In such case, we need to compare local files not to their TIP content, but to specific version at the time of selected revision + Nodeid dirstateParentRev = getDirstate().parents()[0]; + Nodeid lastCsetRev = repo.getChangelog().getRevision(HgRepository.TIP); + if (lastCsetRev.equals(dirstateParentRev)) { + baseRevision = repo.getChangelog().getLastRevision(); + } else { + // can do it right away, but explicit check above might save few cycles (unless getLocalRevision(Nodeid) is effective) + baseRevision = repo.getChangelog().getLocalRevision(dirstateParentRev); + } } + final boolean isTipBase = baseRevision == repo.getChangelog().getLastRevision(); ManifestRevision collect = null; Set<String> baseRevFiles = Collections.emptySet(); // files from base revision not affected by status calculation if (!isTipBase) { @@ -289,8 +300,16 @@ if ((r = getDirstate().checkNormal(fname)) != null || (r = getDirstate().checkMerged(fname)) != null || (r = getDirstate().checkAdded(fname)) != null) { // either clean or modified HgDataFile fileNode = repo.getFileNode(fname); - final int lengthAtRevision = fileNode.length(nid1); - if (r.size /* XXX File.length() ?! */ != lengthAtRevision || flags != todoGenerateFlags(fname /*java.io.File*/)) { + 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*/)) { inspector.modified(fname); } else { // check actual content to see actual changes