Mercurial > jhg
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. |
