# HG changeset patch # User Artem Tikhomirov # Date 1361990278 -3600 # Node ID d3c71498919c860328e3ed813c45153915872308 # Parent 52263817b99806e54ef2c09b39fa81366b94808b Do not process child revisions before all possible parent paths were visited diff -r 52263817b998 -r d3c71498919c src/org/tmatesoft/hg/internal/IntVector.java --- a/src/org/tmatesoft/hg/internal/IntVector.java Tue Feb 26 21:06:43 2013 +0100 +++ b/src/org/tmatesoft/hg/internal/IntVector.java Wed Feb 27 19:37:58 2013 +0100 @@ -16,6 +16,8 @@ */ package org.tmatesoft.hg.internal; +import java.util.Arrays; + /** * Vector of primitive values * @@ -101,6 +103,18 @@ } } + /** + * + * @param ascending true to sort in ascending order, false for descending + */ + public void sort(boolean ascending) { + Arrays.sort(data, 0, count); + if (!ascending) { + reverse(); + } + } + + @Override public String toString() { return String.format("%s[%d]", IntVector.class.getSimpleName(), size()); diff -r 52263817b998 -r d3c71498919c src/org/tmatesoft/hg/internal/RangeSeq.java --- a/src/org/tmatesoft/hg/internal/RangeSeq.java Tue Feb 26 21:06:43 2013 +0100 +++ b/src/org/tmatesoft/hg/internal/RangeSeq.java Wed Feb 27 19:37:58 2013 +0100 @@ -170,6 +170,6 @@ @Override public String toString() { - return String.format("RangeSeq[%d]", count); + return String.format("RangeSeq[%d]:%s", count, dump()); } } \ No newline at end of file diff -r 52263817b998 -r d3c71498919c src/org/tmatesoft/hg/repo/HgBlameFacility.java --- a/src/org/tmatesoft/hg/repo/HgBlameFacility.java Tue Feb 26 21:06:43 2013 +0100 +++ b/src/org/tmatesoft/hg/repo/HgBlameFacility.java Wed Feb 27 19:37:58 2013 +0100 @@ -80,7 +80,9 @@ df.parents(i, fileRevParents, null, null); fileParentRevs.add(fileRevParents[0], fileRevParents[1]); } - // collect file revisions to visit, from newest to oldest + // collect file revisions to visit, from newest to oldest: + // traverse parents, starting from the given file revision + // this ignores all file revision made in parallel to the one of interest IntVector fileRevsToVisit = new IntVector(fileRevIndex + 1, 0); LinkedList queue = new LinkedList(); BitSet seen = new BitSet(fileRevIndex + 1); @@ -102,6 +104,8 @@ } } while (!queue.isEmpty()); FileLinesCache fileInfoCache = new FileLinesCache(df, 10); + // make sure no child is processed before we handled all (grand-)parents of the element + fileRevsToVisit.sort(false); // fileRevsToVisit now { r10, r7, r6, r5, r0 } // and we'll iterate it from behind, e.g. old to new unless reversed if (iterateOrder == HgIterateDirection.NewToOld) { diff -r 52263817b998 -r d3c71498919c test/org/tmatesoft/hg/test/TestBlame.java --- a/test/org/tmatesoft/hg/test/TestBlame.java Tue Feb 26 21:06:43 2013 +0100 +++ b/test/org/tmatesoft/hg/test/TestBlame.java Wed Feb 27 19:37:58 2013 +0100 @@ -97,15 +97,15 @@ FileAnnotation.annotate(df, cs, fa); op.reset(); - eh.run("hg", "annotate", "-r", cs == TIP ? "tip" : String.valueOf(cs), df.getPath().toString()); + eh.run("hg", "annotate", "--no-follow", "-r", cs == TIP ? "tip" : String.valueOf(cs), df.getPath().toString()); String[] hgAnnotateLines = splitLines(op.result()); assertTrue("[sanity]", hgAnnotateLines.length > 0); assertEquals("Number of lines reported by native annotate and our impl", hgAnnotateLines.length, fa.lineRevisions.length); for (int i = 0; i < fa.lineRevisions.length; i++) { - int hgAnnotateRevIndex = Integer.parseInt(hgAnnotateLines[i].substring(0, hgAnnotateLines[i].indexOf(':'))); - errorCollector.assertEquals(String.format("Revision mismatch for line %d", i+1), hgAnnotateRevIndex, fa.lineRevisions[i]); + int hgAnnotateRevIndex = Integer.parseInt(hgAnnotateLines[i].substring(0, hgAnnotateLines[i].indexOf(':')).trim()); + errorCollector.assertEquals(String.format("Revision mismatch for line %d (annotating rev: %d)", i+1, cs), hgAnnotateRevIndex, fa.lineRevisions[i]); String hgAnnotateLine = hgAnnotateLines[i].substring(hgAnnotateLines[i].indexOf(':') + 1); String apiLine = fa.line(i).trim(); errorCollector.assertEquals(hgAnnotateLine.trim(), apiLine); @@ -264,26 +264,33 @@ af.annotate(df, checkChangeset, dump, HgIterateDirection.OldToNew); } - private void ccc() throws Exception { - HgRepository repo = new HgLookup().detect("/home/artem/hg/junit-test-repos/test-annotate/"); - HgDataFile df = repo.getFileNode("file1"); + private void ccc() throws Throwable { + HgRepository repo = new HgLookup().detect("/home/artem/hg/hgtest-annotate1/"); + HgDataFile df = repo.getFileNode("file1b.txt"); HgBlameFacility af = new HgBlameFacility(); -// DiffOutInspector dump = new DiffOutInspector(System.out); -// dump.needRevisions(true); -// af.annotate(df, TIP, dump, HgIterateDirection.OldToNew); + DiffOutInspector dump = new DiffOutInspector(System.out); + dump.needRevisions(true); +// af.annotate(df, 62, dump, HgIterateDirection.NewToOld); +// af.annotateSingleRevision(df, 113, dump); // System.out.println(); // af.annotate(df, TIP, new LineDumpInspector(true), HgIterateDirection.NewToOld); // System.out.println(); // af.annotate(df, TIP, new LineDumpInspector(false), HgIterateDirection.NewToOld); // System.out.println(); + OutputParser.Stub op = new OutputParser.Stub(); + eh = new ExecHelper(op, repo.getWorkingDir()); + for (int cs : new int[] { 24, 46, 49, 52, 59, 62, 64, TIP}) { + doLineAnnotateTest(df, cs, op); + } + errorCollector.verify(); FileAnnotateInspector fa = new FileAnnotateInspector(); - FileAnnotation.annotate(df, TIP, fa); //4,6,TIP + FileAnnotation.annotate(df, 62, fa); for (int i = 0; i < fa.lineRevisions.length; i++) { System.out.printf("%d: %s", fa.lineRevisions[i], fa.line(i) == null ? "null\n" : fa.line(i)); } } - public static void main(String[] args) throws Exception { + public static void main(String[] args) throws Throwable { // System.out.println(Arrays.equals(new String[0], splitLines(""))); // System.out.println(Arrays.equals(new String[] { "abc" }, splitLines("abc"))); // System.out.println(Arrays.equals(new String[] { "a", "bc" }, splitLines("a\nbc")));