comparison 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
comparison
equal deleted inserted replaced
274:9fb50c04f03c 275:6d1804fe0ed7
57 private final HgRepository repo; 57 private final HgRepository repo;
58 private final FileIterator repoWalker; 58 private final FileIterator repoWalker;
59 private HgDirstate dirstate; 59 private HgDirstate dirstate;
60 private HgStatusCollector baseRevisionCollector; 60 private HgStatusCollector baseRevisionCollector;
61 private PathPool pathPool; 61 private PathPool pathPool;
62 private ManifestRevision dirstateParentManifest;
62 63
63 public HgWorkingCopyStatusCollector(HgRepository hgRepo) { 64 public HgWorkingCopyStatusCollector(HgRepository hgRepo) {
64 this(hgRepo, new HgInternals(hgRepo).createWorkingDirWalker(null)); 65 this(hgRepo, new HgInternals(hgRepo).createWorkingDirWalker(null));
65 } 66 }
66 67
98 if (dirstate == null) { 99 if (dirstate == null) {
99 dirstate = repo.loadDirstate(); 100 dirstate = repo.loadDirstate();
100 } 101 }
101 return dirstate; 102 return dirstate;
102 } 103 }
103 104
104 // may be invoked few times 105 // may be invoked few times
106 // NOTE, use of TIP constant requires certain care. TIP here doesn't mean latest cset, but actual working copy parent.
107 // XXX this shall be changed, though, and use of TIP throughout code shall be revised -
108 // consider case when repository is updated to one of its previous revisions. TIP points to last change, but a lot of
109 // commands need to work with revision that is in dirstate now.
105 public void walk(int baseRevision, HgStatusInspector inspector) { 110 public void walk(int baseRevision, HgStatusInspector inspector) {
106 if (HgInternals.wrongLocalRevision(baseRevision) || baseRevision == BAD_REVISION || baseRevision == WORKING_COPY) { 111 if (HgInternals.wrongLocalRevision(baseRevision) || baseRevision == BAD_REVISION || baseRevision == WORKING_COPY) {
107 throw new IllegalArgumentException(String.valueOf(baseRevision)); 112 throw new IllegalArgumentException(String.valueOf(baseRevision));
108 } 113 }
109 final HgIgnore hgIgnore = repo.getIgnore(); 114 final HgIgnore hgIgnore = repo.getIgnore();
110 TreeSet<String> knownEntries = getDirstate().all(); 115 TreeSet<String> knownEntries = getDirstate().all();
111 final boolean isTipBase;
112 if (baseRevision == TIP) { 116 if (baseRevision == TIP) {
113 baseRevision = repo.getChangelog().getLastRevision(); 117 // WC not necessarily points to TIP, but may be result of update to any previous revision.
114 isTipBase = true; 118 // In such case, we need to compare local files not to their TIP content, but to specific version at the time of selected revision
115 } else { 119 Nodeid dirstateParentRev = getDirstate().parents()[0];
116 isTipBase = baseRevision == repo.getChangelog().getLastRevision(); 120 Nodeid lastCsetRev = repo.getChangelog().getRevision(HgRepository.TIP);
117 } 121 if (lastCsetRev.equals(dirstateParentRev)) {
122 baseRevision = repo.getChangelog().getLastRevision();
123 } else {
124 // can do it right away, but explicit check above might save few cycles (unless getLocalRevision(Nodeid) is effective)
125 baseRevision = repo.getChangelog().getLocalRevision(dirstateParentRev);
126 }
127 }
128 final boolean isTipBase = baseRevision == repo.getChangelog().getLastRevision();
118 ManifestRevision collect = null; 129 ManifestRevision collect = null;
119 Set<String> baseRevFiles = Collections.emptySet(); // files from base revision not affected by status calculation 130 Set<String> baseRevFiles = Collections.emptySet(); // files from base revision not affected by status calculation
120 if (!isTipBase) { 131 if (!isTipBase) {
121 if (baseRevisionCollector != null) { 132 if (baseRevisionCollector != null) {
122 collect = baseRevisionCollector.raw(baseRevision); 133 collect = baseRevisionCollector.raw(baseRevision);
287 // was known; check whether clean or modified 298 // was known; check whether clean or modified
288 // when added - seems to be the case of a file added once again, hence need to check if content is different 299 // when added - seems to be the case of a file added once again, hence need to check if content is different
289 if ((r = getDirstate().checkNormal(fname)) != null || (r = getDirstate().checkMerged(fname)) != null || (r = getDirstate().checkAdded(fname)) != null) { 300 if ((r = getDirstate().checkNormal(fname)) != null || (r = getDirstate().checkMerged(fname)) != null || (r = getDirstate().checkAdded(fname)) != null) {
290 // either clean or modified 301 // either clean or modified
291 HgDataFile fileNode = repo.getFileNode(fname); 302 HgDataFile fileNode = repo.getFileNode(fname);
292 final int lengthAtRevision = fileNode.length(nid1); 303 int lengthAtRevision;
293 if (r.size /* XXX File.length() ?! */ != lengthAtRevision || flags != todoGenerateFlags(fname /*java.io.File*/)) { 304 try {
305 lengthAtRevision = fileNode.length(nid1);
306 } catch (HgDataStreamException ex) {
307 ex.printStackTrace(); // XXX log error
308 lengthAtRevision = -1; // compare file content then
309 }
310 // XXX is it safe with respect to filters (keyword, eol) to compare lengthAtRevision (unprocessed) with size
311 // from dirstate, which I assume is size of processed data?
312 if (r.size != -1 && r.size /* XXX File.length() ?! */ != lengthAtRevision || flags != todoGenerateFlags(fname /*java.io.File*/)) {
294 inspector.modified(fname); 313 inspector.modified(fname);
295 } else { 314 } else {
296 // check actual content to see actual changes 315 // check actual content to see actual changes
297 if (areTheSame(f, fileNode, fileNode.getLocalRevision(nid1))) { 316 if (areTheSame(f, fileNode, fileNode.getLocalRevision(nid1))) {
298 inspector.clean(fname); 317 inspector.clean(fname);