comparison src/org/tmatesoft/hg/repo/HgStatusCollector.java @ 690:b286222158be

Fix file.isCopy() use for status and cat commands
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 01 Aug 2013 21:45:47 +0200
parents 5050ee565bd1
children 72fc7774b87e
comparison
equal deleted inserted replaced
689:5050ee565bd1 690:b286222158be
296 r1 = get(rev1); 296 r1 = get(rev1);
297 r2 = get(rev2); 297 r2 = get(rev2);
298 298
299 final CancelSupport cs = CancelSupport.Factory.get(inspector); 299 final CancelSupport cs = CancelSupport.Factory.get(inspector);
300 300
301 TreeSet<Path> r1Files = new TreeSet<Path>(r1.files()); 301
302 Collection<Path> allBaseFiles = r1.files();
303 TreeSet<Path> r1Files = new TreeSet<Path>(allBaseFiles);
302 for (Path r2fname : r2.files()) { 304 for (Path r2fname : r2.files()) {
303 if (!scope.accept(r2fname)) { 305 if (!scope.accept(r2fname)) {
304 continue; 306 continue;
305 } 307 }
306 if (r1Files.remove(r2fname)) { 308 if (r1Files.remove(r2fname)) {
315 } 317 }
316 cs.checkCancelled(); 318 cs.checkCancelled();
317 } else { 319 } else {
318 try { 320 try {
319 Path copyTarget = r2fname; 321 Path copyTarget = r2fname;
320 Path copyOrigin = detectCopies ? getOriginIfCopy(repo, copyTarget, r2.nodeid(copyTarget), r1Files, rev1) : null; 322 Path copyOrigin = detectCopies ? getOriginIfCopy(repo, copyTarget, r2.nodeid(copyTarget), allBaseFiles, rev1) : null;
321 if (copyOrigin != null) { 323 if (copyOrigin != null) {
322 inspector.copied(getPathPool().mangle(copyOrigin) /*pipe through pool, just in case*/, copyTarget); 324 inspector.copied(getPathPool().mangle(copyOrigin) /*pipe through pool, just in case*/, copyTarget);
323 } else { 325 } else {
324 inspector.added(copyTarget); 326 inspector.added(copyTarget);
325 } 327 }
360 throw t; 362 throw t;
361 } 363 }
362 return rv; 364 return rv;
363 } 365 }
364 366
367 // originals shall include all names known in base revision, not those not yet consumed
368 // see TestStatus#testDetectRenamesInNonFirstRev and log-renames test repository
369 // where a and d in r5 are compared to a and b in r1, while d is in fact descendant of original a, and a is original b (through c)
365 /*package-local*/static Path getOriginIfCopy(HgRepository hgRepo, Path fname, Nodeid fnameRev, Collection<Path> originals, int originalChangesetIndex) throws HgRuntimeException { 370 /*package-local*/static Path getOriginIfCopy(HgRepository hgRepo, Path fname, Nodeid fnameRev, Collection<Path> originals, int originalChangesetIndex) throws HgRuntimeException {
366 HgDataFile df = hgRepo.getFileNode(fname); 371 HgDataFile df = hgRepo.getFileNode(fname);
367 if (!df.exists()) { 372 if (!df.exists()) {
368 String msg = String.format("Didn't find file '%s' in the repo. Perhaps, bad storage name conversion?", fname); 373 String msg = String.format("Didn't find file '%s' in the repo. Perhaps, bad storage name conversion?", fname);
369 throw new HgInvalidFileException(msg, null).setFileName(fname).setRevisionIndex(originalChangesetIndex); 374 throw new HgInvalidFileException(msg, null).setFileName(fname).setRevisionIndex(originalChangesetIndex);
378 continue; 383 continue;
379 } 384 }
380 int csetRevIndex = df.getChangesetRevisionIndex(fileRevIndex); 385 int csetRevIndex = df.getChangesetRevisionIndex(fileRevIndex);
381 if (csetRevIndex <= originalChangesetIndex) { 386 if (csetRevIndex <= originalChangesetIndex) {
382 // we've walked past originalChangelogRevIndex and no chances we'll find origin 387 // we've walked past originalChangelogRevIndex and no chances we'll find origin
383 // if we get here, it means fname's origin is not from the base revision 388 // if we get here, it means either fname's origin is not from the base revision
384 return null; 389 // or the last found rename is still valid
390 return lastOriginFound;
385 } 391 }
386 HgFileRevision origin = df.getCopySource(fileRevIndex); 392 HgFileRevision origin = df.getCopySource(fileRevIndex);
387 // prepare for the next step, df(copyFromFileRev) would point to copy origin and its revision 393 // prepare for the next step, df(copyFromFileRev) would point to copy origin and its revision
388 df = hgRepo.getFileNode(origin.getPath()); 394 df = hgRepo.getFileNode(origin.getPath());
389 int copyFromFileRevIndex = df.getRevisionIndex(origin.getRevision()); 395 int copyFromFileRevIndex = df.getRevisionIndex(origin.getRevision());
398 } 404 }
399 // copy/rename happened in [copyFromCsetIndex..target], let's see if 405 // copy/rename happened in [copyFromCsetIndex..target], let's see if
400 // origin wasn't renamed once more in [originalChangesetIndex..copyFromCsetIndex] 406 // origin wasn't renamed once more in [originalChangesetIndex..copyFromCsetIndex]
401 lastOriginFound = origin.getPath(); 407 lastOriginFound = origin.getPath();
402 // FALL-THROUGH 408 // FALL-THROUGH
409 } else {
410 // clear last known origin if the file was renamed once again to something we don't have in base
411 lastOriginFound = null;
403 } 412 }
404 // try more steps away 413 // try more steps away
405 // copyFromFileRev or one of its predecessors might be copies as well 414 // copyFromFileRev or one of its predecessors might be copies as well
406 fileRevIndex = copyFromFileRevIndex; // df is already origin file 415 fileRevIndex = copyFromFileRevIndex; // df is already origin file
407 } 416 }