Mercurial > hg4j
comparison 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 |
comparison
equal
deleted
inserted
replaced
279:23e3ea855097 | 280:35125450c804 |
---|---|
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; | |
63 | 62 |
64 public HgWorkingCopyStatusCollector(HgRepository hgRepo) { | 63 public HgWorkingCopyStatusCollector(HgRepository hgRepo) { |
65 this(hgRepo, new HgInternals(hgRepo).createWorkingDirWalker(null)); | 64 this(hgRepo, new HgInternals(hgRepo).createWorkingDirWalker(null)); |
66 } | 65 } |
67 | 66 |
143 } | 142 } |
144 repoWalker.reset(); | 143 repoWalker.reset(); |
145 final PathPool pp = getPathPool(); | 144 final PathPool pp = getPathPool(); |
146 while (repoWalker.hasNext()) { | 145 while (repoWalker.hasNext()) { |
147 repoWalker.next(); | 146 repoWalker.next(); |
148 Path fname = pp.path(repoWalker.name()); | 147 final Path fname = pp.path(repoWalker.name()); |
149 File f = repoWalker.file(); | 148 File f = repoWalker.file(); |
150 if (!f.exists()) { | 149 if (!f.exists()) { |
151 // file coming from iterator doesn't exist. | 150 // file coming from iterator doesn't exist. |
152 if (knownEntries.remove(fname.toString())) { | 151 if (knownEntries.remove(fname.toString())) { |
153 if (getDirstate().checkRemoved(fname) == null) { | 152 if (getDirstate().checkRemoved(fname) == null) { |
235 | 234 |
236 private void checkLocalStatusAgainstFile(Path fname, File f, HgStatusInspector inspector) { | 235 private void checkLocalStatusAgainstFile(Path fname, File f, HgStatusInspector inspector) { |
237 HgDirstate.Record r; | 236 HgDirstate.Record r; |
238 if ((r = getDirstate().checkNormal(fname)) != null) { | 237 if ((r = getDirstate().checkNormal(fname)) != null) { |
239 // either clean or modified | 238 // either clean or modified |
240 if (f.lastModified() / 1000 == r.time && r.size == f.length()) { | 239 final boolean timestampEqual = getFileModificationTime(f) == r.time, sizeEqual = r.size == f.length(); |
241 inspector.clean(getPathPool().path(fname)); | 240 if (timestampEqual && sizeEqual) { |
242 } else { | 241 inspector.clean(fname); |
242 } else if (!sizeEqual && r.size >= 0) { | |
243 inspector.modified(fname); | |
244 } else { | |
245 // size is the same or unknown, and, perhaps, different timestamp | |
243 // check actual content to avoid false modified files | 246 // check actual content to avoid false modified files |
244 HgDataFile df = repo.getFileNode(fname); | 247 HgDataFile df = repo.getFileNode(fname); |
245 if (!areTheSame(f, df, HgRepository.TIP)) { | 248 if (!areTheSame(f, df, HgRepository.TIP)) { |
246 inspector.modified(df.getPath()); | 249 inspector.modified(df.getPath()); |
247 } else { | 250 } else { |
248 inspector.clean(df.getPath()); | 251 inspector.clean(df.getPath()); |
249 } | 252 } |
250 } | 253 } |
251 } else if ((r = getDirstate().checkAdded(fname)) != null) { | 254 } else if ((r = getDirstate().checkAdded(fname)) != null) { |
252 if (r.name2 == null) { | 255 if (r.name2 == null) { |
253 inspector.added(getPathPool().path(fname)); | 256 inspector.added(fname); |
254 } else { | 257 } else { |
255 inspector.copied(getPathPool().path(r.name2), getPathPool().path(fname)); | 258 inspector.copied(getPathPool().path(r.name2), fname); |
256 } | 259 } |
257 } else if ((r = getDirstate().checkRemoved(fname)) != null) { | 260 } else if ((r = getDirstate().checkRemoved(fname)) != null) { |
258 inspector.removed(getPathPool().path(fname)); | 261 inspector.removed(fname); |
259 } else if ((r = getDirstate().checkMerged(fname)) != null) { | 262 } else if ((r = getDirstate().checkMerged(fname)) != null) { |
260 inspector.modified(getPathPool().path(fname)); | 263 inspector.modified(fname); |
261 } | 264 } |
265 } | |
266 | |
267 // return mtime analog, directly comparable to dirstate's mtime. | |
268 private static int getFileModificationTime(File f) { | |
269 return (int) (f.lastModified() / 1000); | |
262 } | 270 } |
263 | 271 |
264 // XXX refactor checkLocalStatus methods in more OO way | 272 // XXX refactor checkLocalStatus methods in more OO way |
265 private void checkLocalStatusAgainstBaseRevision(Set<String> baseRevNames, ManifestRevision collect, int baseRevision, Path fname, File f, HgStatusInspector inspector) { | 273 private void checkLocalStatusAgainstBaseRevision(Set<String> baseRevNames, ManifestRevision collect, int baseRevision, Path fname, File f, HgStatusInspector inspector) { |
266 // fname is in the dirstate, either Normal, Added, Removed or Merged | 274 // fname is in the dirstate, either Normal, Added, Removed or Merged |
294 return; | 302 return; |
295 } | 303 } |
296 inspector.added(fname); | 304 inspector.added(fname); |
297 } else { | 305 } else { |
298 // was known; check whether clean or modified | 306 // was known; check whether clean or modified |
299 // when added - seems to be the case of a file added once again, hence need to check if content is different | 307 if ((r = getDirstate().checkNormal(fname)) != null) { |
300 if ((r = getDirstate().checkNormal(fname)) != null || (r = getDirstate().checkMerged(fname)) != null || (r = getDirstate().checkAdded(fname)) != null) { | 308 final boolean timestampEqual = getFileModificationTime(f) == r.time, sizeEqual = r.size == f.length(); |
309 if (timestampEqual && sizeEqual) { | |
310 inspector.clean(fname); | |
311 baseRevNames.remove(fname.toString()); // consumed, processed, handled. | |
312 return; | |
313 } else if (!sizeEqual && r.size >= 0) { | |
314 inspector.modified(fname); | |
315 baseRevNames.remove(fname.toString()); // consumed, processed, handled. | |
316 return; | |
317 } | |
318 // otherwise, shall check actual content (size not the same, or unknown (-1 or -2), or timestamp is different) | |
319 // FALL THROUGH | |
320 } | |
321 if (r != null /*Normal dirstate, but needs extra check*/ || (r = getDirstate().checkMerged(fname)) != null || (r = getDirstate().checkAdded(fname)) != null) { | |
322 // when added - seems to be the case of a file added once again, hence need to check if content is different | |
301 // either clean or modified | 323 // either clean or modified |
302 HgDataFile fileNode = repo.getFileNode(fname); | 324 if (r.size != -1 /*XXX what about ==-2?*/&& r.size != f.length() || !todoCheckFlagsEqual(f, flags)) { |
303 int lengthAtRevision; | |
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*/)) { | |
313 inspector.modified(fname); | 325 inspector.modified(fname); |
314 } else { | 326 } else { |
315 // check actual content to see actual changes | 327 // check actual content to see actual changes |
328 HgDataFile fileNode = repo.getFileNode(fname); | |
316 if (areTheSame(f, fileNode, fileNode.getLocalRevision(nid1))) { | 329 if (areTheSame(f, fileNode, fileNode.getLocalRevision(nid1))) { |
317 inspector.clean(fname); | 330 inspector.clean(fname); |
318 } else { | 331 } else { |
319 inspector.modified(fname); | 332 inspector.modified(fname); |
320 } | 333 } |
410 ex.printStackTrace(); | 423 ex.printStackTrace(); |
411 } | 424 } |
412 return false; | 425 return false; |
413 } | 426 } |
414 | 427 |
415 private static String todoGenerateFlags(Path fname) { | 428 private static boolean todoCheckFlagsEqual(File f, String manifestFlags) { |
416 // FIXME implement | 429 // FIXME implement |
417 return null; | 430 return true; |
418 } | 431 } |
419 | 432 |
420 /** | 433 /** |
421 * Configure status collector to consider only subset of a working copy tree. Tries to be as effective as possible, and to | 434 * Configure status collector to consider only subset of a working copy tree. Tries to be as effective as possible, and to |
422 * traverse only relevant part of working copy on the filesystem. | 435 * traverse only relevant part of working copy on the filesystem. |