comparison src/org/tmatesoft/hg/repo/HgStatusCollector.java @ 691:72fc7774b87e

Fix file.isCopy() for blame/annotate. Refactor status and blame to use newly introduced FileHistory helper that builds file rename history
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 02 Aug 2013 23:07:23 +0200
parents b286222158be
children 7efabe0cddcf
comparison
equal deleted inserted replaced
690:b286222158be 691:72fc7774b87e
24 import java.util.LinkedList; 24 import java.util.LinkedList;
25 import java.util.List; 25 import java.util.List;
26 import java.util.Map; 26 import java.util.Map;
27 import java.util.TreeSet; 27 import java.util.TreeSet;
28 28
29 import org.tmatesoft.hg.core.HgFileRevision;
30 import org.tmatesoft.hg.core.Nodeid; 29 import org.tmatesoft.hg.core.Nodeid;
30 import org.tmatesoft.hg.internal.FileRenameHistory;
31 import org.tmatesoft.hg.internal.FileRenameHistory.Chunk;
31 import org.tmatesoft.hg.internal.IntMap; 32 import org.tmatesoft.hg.internal.IntMap;
32 import org.tmatesoft.hg.internal.ManifestRevision; 33 import org.tmatesoft.hg.internal.ManifestRevision;
33 import org.tmatesoft.hg.internal.Pool; 34 import org.tmatesoft.hg.internal.Pool;
34 import org.tmatesoft.hg.util.CancelSupport; 35 import org.tmatesoft.hg.util.CancelSupport;
35 import org.tmatesoft.hg.util.CancelledException; 36 import org.tmatesoft.hg.util.CancelledException;
374 throw new HgInvalidFileException(msg, null).setFileName(fname).setRevisionIndex(originalChangesetIndex); 375 throw new HgInvalidFileException(msg, null).setFileName(fname).setRevisionIndex(originalChangesetIndex);
375 } 376 }
376 assert fnameRev != null; 377 assert fnameRev != null;
377 assert !Nodeid.NULL.equals(fnameRev); 378 assert !Nodeid.NULL.equals(fnameRev);
378 int fileRevIndex = fnameRev == null ? 0 : df.getRevisionIndex(fnameRev); 379 int fileRevIndex = fnameRev == null ? 0 : df.getRevisionIndex(fnameRev);
379 Path lastOriginFound = null; 380 FileRenameHistory frh = new FileRenameHistory(originalChangesetIndex, df.getChangesetRevisionIndex(fileRevIndex));
380 while(fileRevIndex >=0) { 381 if (frh.isOutOfRange(df, fileRevIndex)) {
381 if (!df.isCopy(fileRevIndex)) { 382 return null;
382 fileRevIndex--; 383 }
383 continue; 384 frh.build(df, fileRevIndex);
384 } 385 Chunk c = frh.chunkAt(originalChangesetIndex);
385 int csetRevIndex = df.getChangesetRevisionIndex(fileRevIndex); 386 if (c == null) {
386 if (csetRevIndex <= originalChangesetIndex) { 387 // file rename history doesn't go deep up to changeset of interest
387 // we've walked past originalChangelogRevIndex and no chances we'll find origin 388 return null;
388 // if we get here, it means either fname's origin is not from the base revision 389 }
389 // or the last found rename is still valid 390 Path nameAtOrigin = c.file().getPath();
390 return lastOriginFound; 391 if (originals.contains(nameAtOrigin)) {
391 } 392 return nameAtOrigin;
392 HgFileRevision origin = df.getCopySource(fileRevIndex); 393 }
393 // prepare for the next step, df(copyFromFileRev) would point to copy origin and its revision 394 return null;
394 df = hgRepo.getFileNode(origin.getPath());
395 int copyFromFileRevIndex = df.getRevisionIndex(origin.getRevision());
396 if (originals.contains(origin.getPath())) {
397 int copyFromCsetIndex = df.getChangesetRevisionIndex(copyFromFileRevIndex);
398 if (copyFromCsetIndex <= originalChangesetIndex) {
399 // copy/rename source was known prior to rev1
400 // (both r1Files.contains is true and original was created earlier than rev1)
401 // without r1Files.contains changelogRevision <= rev1 won't suffice as the file
402 // might get removed somewhere in between (changelogRevision < R < rev1)
403 return origin.getPath();
404 }
405 // copy/rename happened in [copyFromCsetIndex..target], let's see if
406 // origin wasn't renamed once more in [originalChangesetIndex..copyFromCsetIndex]
407 lastOriginFound = origin.getPath();
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;
412 }
413 // try more steps away
414 // copyFromFileRev or one of its predecessors might be copies as well
415 fileRevIndex = copyFromFileRevIndex; // df is already origin file
416 }
417 return lastOriginFound;
418 } 395 }
419 396
420 // XXX for r1..r2 status, only modified, added, removed (and perhaps, clean) make sense 397 // XXX for r1..r2 status, only modified, added, removed (and perhaps, clean) make sense
421 // XXX Need to specify whether copy targets are in added or not (@see Inspector#copied above) 398 // XXX Need to specify whether copy targets are in added or not (@see Inspector#copied above)
422 /** 399 /**