# HG changeset patch # User Artem Tikhomirov # Date 1361556205 -3600 # Node ID e623aa2ca526e18a06c29fb200279310fd2a799e # Parent a5fd757d1b5dfb329fbced29c2d887709fe9e5fe Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision diff -r a5fd757d1b5d -r e623aa2ca526 src/org/tmatesoft/hg/internal/AnnotateFacility.java --- a/src/org/tmatesoft/hg/internal/AnnotateFacility.java Thu Feb 21 21:53:55 2013 +0100 +++ b/src/org/tmatesoft/hg/internal/AnnotateFacility.java Fri Feb 22 19:03:25 2013 +0100 @@ -25,15 +25,18 @@ import org.tmatesoft.hg.core.HgIterateDirection; import org.tmatesoft.hg.core.Nodeid; -import org.tmatesoft.hg.internal.AnnotateFacility.BlockData; +import org.tmatesoft.hg.internal.AnnotateFacility.RevisionDescriptor.Recipient; import org.tmatesoft.hg.internal.DiffHelper.LineSequence; import org.tmatesoft.hg.internal.DiffHelper.LineSequence.ByteChain; import org.tmatesoft.hg.repo.HgDataFile; import org.tmatesoft.hg.repo.HgInvalidStateException; +import org.tmatesoft.hg.repo.HgRepository; +import org.tmatesoft.hg.util.Adaptable; import org.tmatesoft.hg.util.CancelledException; import org.tmatesoft.hg.util.Pair; /** + * Facility with diff/annotate functionality. * * @author Artem Tikhomirov * @author TMate Software Ltd. @@ -55,6 +58,9 @@ pg.findMatchingBlocks(new BlameBlockInspector(insp, clogRevIndex1, clogRevIndex2)); } + /** + * Walk file history up to revision at given changeset and report changes for each revision + */ public void annotate(HgDataFile df, int changelogRevisionIndex, BlockInspector insp, HgIterateDirection iterateOrder) { if (!df.exists()) { return; @@ -107,20 +113,11 @@ } /** - * Annotate file revision, line by line. + * Annotates changes of the file against its parent(s). + * Unlike {@link #annotate(HgDataFile, int, BlockInspector, HgIterateDirection)}, doesn't + * walk file history, looks at the specified revision only. Handles both parents (if merge revision). */ - public void annotate(HgDataFile df, int changelogRevisionIndex, LineInspector insp) { - if (!df.exists()) { - return; - } - FileAnnotation fa = new FileAnnotation(insp); - annotate(df, changelogRevisionIndex, fa, HgIterateDirection.NewToOld); - } - - /** - * Annotates changes of the file against its parent(s) - */ - public void annotateChange(HgDataFile df, int changelogRevisionIndex, BlockInspector insp) { + public void annotateSingleRevision(HgDataFile df, int changelogRevisionIndex, BlockInspector insp) { // TODO detect if file is text/binary (e.g. looking for chars < ' ' and not \t\r\n\f int fileRevIndex = fileRevIndex(df, changelogRevisionIndex); int[] fileRevParents = new int[2]; @@ -233,6 +230,14 @@ } } + /** + * Client's sink for revision differences. + * + * When implemented, clients shall not expect new {@link Block blocks} instances in each call. + * + * In case more information about annotated revision is needed, inspector instances may supply + * {@link RevisionDescriptor.Recipient} through {@link Adaptable}. + */ @Callback public interface BlockInspector { void same(EqualBlock block); @@ -241,13 +246,6 @@ void deleted(DeleteBlock block); } - @Callback - public interface BlockInspectorEx extends BlockInspector { // XXX better name - // XXX perhaps, shall pass object instead of separate values for future extension? - void start(BlockData originContent, BlockData targetContent); - void done(); - } - /** * Represents content of a block, either as a sequence of bytes or a * sequence of smaller blocks (lines), if appropriate (according to usage context). @@ -276,14 +274,65 @@ byte[] asArray(); } + /** + * {@link BlockInspector} may optionally request extra information about revisions + * being inspected, denoting itself as a {@link RevisionDescriptor.Recipient}. This class + * provides complete information about file revision under annotation now. + */ + public interface RevisionDescriptor { + /** + * @return complete source of the diff origin, never null + */ + BlockData origin(); + /** + * @return complete source of the diff target, never null + */ + BlockData target(); + /** + * @return changeset revision index of original file, or {@link HgRepository#NO_REVISION} if it's the very first revision + */ + int originChangesetIndex(); + /** + * @return changeset revision index of the target file + */ + int targetChangesetIndex(); + /** + * @return true if this revision is merge + */ + boolean isMerge(); + /** + * @return changeset revision index of the second, merged parent + */ + int mergeChangesetIndex(); + /** + * @return revision index of the change in file's revlog + */ + int fileRevisionIndex(); + + /** + * Implement to indicate interest in {@link RevisionDescriptor}. + * + * Note, instance of {@link RevisionDescriptor} is the same for + * {@link #start(RevisionDescriptor)} and {@link #done(RevisionDescriptor)} + * methods, and not necessarily a new one (i.e. ==) for the next + * revision announced. + */ + @Callback + public interface Recipient { + /** + * Comes prior to any change {@link Block blocks} + */ + void start(RevisionDescriptor revisionDescription); + /** + * Comes after all change {@link Block blocks} were dispatched + */ + void done(RevisionDescriptor revisionDescription); + } + } + public interface Block { int originChangesetIndex(); int targetChangesetIndex(); -// boolean isMergeRevision(); -// int fileRevisionIndex(); -// int originFileRevisionIndex(); -// String[] lines(); -// byte[] data(); } public interface EqualBlock extends Block { @@ -308,32 +357,19 @@ public interface ChangeBlock extends AddBlock, DeleteBlock { } - @Callback - public interface LineInspector { - /** - * Not necessarily invoked sequentially by line numbers - */ - void line(int lineNumber, int changesetRevIndex, LineDescriptor ld); - } - - public interface LineDescriptor { - int totalLines(); - } - - - - static class BlameBlockInspector extends DiffHelper.DeltaInspector { + private static class BlameBlockInspector extends DiffHelper.DeltaInspector { private final BlockInspector insp; private final int csetOrigin; private final int csetTarget; private EqualBlocksCollector p2MergeCommon; private int csetMergeParent; private IntVector mergeRanges; - private ContentBlock originContent, targetContent; + private final AnnotateRev annotatedRevision; public BlameBlockInspector(BlockInspector inspector, int originCset, int targetCset) { assert inspector != null; insp = inspector; + annotatedRevision = new AnnotateRev(); csetOrigin = originCset; csetTarget = targetCset; } @@ -347,19 +383,24 @@ @Override public void begin(LineSequence s1, LineSequence s2) { super.begin(s1, s2); - originContent = new ContentBlock(s1); - targetContent = new ContentBlock(s2); - if (insp instanceof BlockInspectorEx) { - ((BlockInspectorEx) insp).start(originContent, targetContent); + ContentBlock originContent = new ContentBlock(s1); + ContentBlock targetContent = new ContentBlock(s2); + annotatedRevision.set(originContent, targetContent); + annotatedRevision.set(csetOrigin, csetTarget, p2MergeCommon != null ? csetMergeParent : NO_REVISION); + Recipient curious = Adaptable.Factory.getAdapter(insp, Recipient.class, null); + if (curious != null) { + curious.start(annotatedRevision); } } @Override public void end() { super.end(); - if(insp instanceof BlockInspectorEx) { - ((BlockInspectorEx) insp).done(); + Recipient curious = Adaptable.Factory.getAdapter(insp, Recipient.class, null); + if (curious != null) { + curious.done(annotatedRevision); } + p2MergeCommon = null; } @Override @@ -387,7 +428,7 @@ // how many lines we may reported as changed (don't use more than in range unless it's the very last range) final int s1LinesToBorrow = lastRange ? s1LinesLeft : Math.min(s1LinesLeft, rangeLen); if (s1LinesToBorrow > 0) { - ChangeBlockImpl block = new ChangeBlockImpl(originContent, targetContent, s1Start, s1LinesToBorrow, rangeStart, rangeLen, s1Start, rangeStart); + ChangeBlockImpl block = getChangeBlock(s1Start, s1LinesToBorrow, rangeStart, rangeLen); block.setOriginAndTarget(rangeOrigin, csetTarget); insp.changed(block); s1ConsumedLines += s1LinesToBorrow; @@ -402,7 +443,7 @@ throw new HgInvalidStateException(String.format("Expected to process %d lines, but actually was %d", s1TotalLines, s1ConsumedLines)); } } else { - ChangeBlockImpl block = new ChangeBlockImpl(originContent, targetContent, s1From, s1To-s1From, s2From, s2To - s2From, s1From, s2From); + ChangeBlockImpl block = getChangeBlock(s1From, s1To-s1From, s2From, s2To - s2From); block.setOriginAndTarget(csetOrigin, csetTarget); insp.changed(block); } @@ -433,24 +474,28 @@ @Override protected void deleted(int s2DeletePoint, int s1From, int s1To) { - ChangeBlockImpl block = new ChangeBlockImpl(originContent, null, s1From, s1To - s1From, -1, -1, -1, s2DeletePoint); + ChangeBlockImpl block = new ChangeBlockImpl(annotatedRevision.origin, null, s1From, s1To - s1From, -1, -1, -1, s2DeletePoint); block.setOriginAndTarget(csetOrigin, csetTarget); insp.deleted(block); } @Override protected void unchanged(int s1From, int s2From, int length) { - EqualBlockImpl block = new EqualBlockImpl(s1From, s2From, length, targetContent); + EqualBlockImpl block = new EqualBlockImpl(s1From, s2From, length, annotatedRevision.target); block.setOriginAndTarget(csetOrigin, csetTarget); insp.same(block); } private ChangeBlockImpl getAddBlock(int start, int len, int insPoint) { - return new ChangeBlockImpl(null, targetContent, -1, -1, start, len, insPoint, -1); + return new ChangeBlockImpl(null, annotatedRevision.target, -1, -1, start, len, insPoint, -1); + } + + private ChangeBlockImpl getChangeBlock(int start1, int end1, int start2, int end2) { + return new ChangeBlockImpl(annotatedRevision.origin, annotatedRevision.target, start1, end1-start1, start2, end2-start2, start1, start2); } } - static class BlockImpl implements Block { + private static class BlockImpl implements Block { private int originCset; private int targetCset; @@ -472,7 +517,7 @@ } } - static class EqualBlockImpl extends BlockImpl implements EqualBlock { + private static class EqualBlockImpl extends BlockImpl implements EqualBlock { private final int start1, start2; private final int length; private final ContentBlock fullContent; @@ -510,7 +555,7 @@ } } - static class ChangeBlockImpl extends BlockImpl implements ChangeBlock { + private static class ChangeBlockImpl extends BlockImpl implements ChangeBlock { private final ContentBlock oldContent; private final ContentBlock newContent; @@ -758,6 +803,49 @@ } } + private static class AnnotateRev implements RevisionDescriptor { + public ContentBlock origin, target; + public int originCset, targetCset, mergeCset, fileRevIndex; + + public void set(ContentBlock o, ContentBlock t) { + origin = o; + target = t; + } + public void set(int o, int t, int m) { + originCset = o; + targetCset = t; + mergeCset = m; + } + + public BlockData origin() { + return origin; + } + + public BlockData target() { + return target; + } + + public int originChangesetIndex() { + return originCset; + } + + public int targetChangesetIndex() { + return targetCset; + } + + public boolean isMerge() { + return mergeCset != NO_REVISION; + } + + public int mergeChangesetIndex() { + return mergeCset; + } + + public int fileRevisionIndex() { + return fileRevIndex; + } + } + public static void main(String[] args) { EqualBlocksCollector bc = new EqualBlocksCollector(); bc.match(-1, 5, 3); diff -r a5fd757d1b5d -r e623aa2ca526 src/org/tmatesoft/hg/internal/FileAnnotation.java --- a/src/org/tmatesoft/hg/internal/FileAnnotation.java Thu Feb 21 21:53:55 2013 +0100 +++ b/src/org/tmatesoft/hg/internal/FileAnnotation.java Fri Feb 22 19:03:25 2013 +0100 @@ -18,179 +18,202 @@ import java.util.LinkedList; -import org.tmatesoft.hg.internal.AnnotateFacility.AddBlock; -import org.tmatesoft.hg.internal.AnnotateFacility.BlockData; -import org.tmatesoft.hg.internal.AnnotateFacility.ChangeBlock; -import org.tmatesoft.hg.internal.AnnotateFacility.DeleteBlock; -import org.tmatesoft.hg.internal.AnnotateFacility.EqualBlock; -import org.tmatesoft.hg.internal.AnnotateFacility.LineInspector; - +import org.tmatesoft.hg.core.HgIterateDirection; +import org.tmatesoft.hg.internal.AnnotateFacility.*; +import org.tmatesoft.hg.repo.HgDataFile; /** + * Produce output like 'hg annotate' does * * @author Artem Tikhomirov * @author TMate Software Ltd. */ -public class FileAnnotation implements AnnotateFacility.BlockInspectorEx { - // blocks deleted in the target, as reported at the previous step - private LinkedList deleted = new LinkedList(); - // blocks deleted in the origin, to become deletions in target at the next step - private LinkedList newDeleted = new LinkedList(); - // keeps of equal blocks, origin to target, from previous step - // XXX smth like IntSliceVector to access triples (or slices of any size, in fact) - // with easy indexing, e.g. #get(sliceIndex, indexWithinSlice) - // and vect.get(7,2) instead of vect.get(7*SIZEOF_SLICE+2) - private IntVector identical = new IntVector(20*3, 2*3); - // equal blocks of the current iteration, to be recalculated before next step - // to track line number (current target to ultimate target) mapping - private IntVector newIdentical = new IntVector(20*3, 2*3); - - private boolean[] knownLines; - private final LineInspector delegate; - - public FileAnnotation(AnnotateFacility.LineInspector lineInspector) { - delegate = lineInspector; - } - - public void start(BlockData originContent, BlockData targetContent) { - if (knownLines == null) { - knownLines = new boolean[targetContent.elementCount()]; - } - } - -// private static void ppp(IntVector v) { -// for (int i = 0; i < v.size(); i+= 3) { -// int len = v.get(i+2); -// System.out.printf("[%d..%d) == [%d..%d); ", v.get(i), v.get(i) + len, v.get(i+1), v.get(i+1) + len); -// } -// System.out.println(); -// } +public class FileAnnotation implements AnnotateFacility.BlockInspector, RevisionDescriptor.Recipient { - public void done() { - if (identical.size() > 0) { - // update line numbers of the intermediate target to point to ultimate target's line numbers - IntVector v = new IntVector(identical.size(), 2*3); - for (int i = 0; i < newIdentical.size(); i+= 3) { - int originLine = newIdentical.get(i); - int targetLine = newIdentical.get(i+1); - int length = newIdentical.get(i+2); - int startTargetLine = -1, startOriginLine = -1, c = 0; - for (int j = 0; j < length; j++) { - int lnInFinal = mapLineIndex(targetLine + j); - if (lnInFinal == -1 || (startTargetLine != -1 && lnInFinal != startTargetLine + c)) { - // the line is not among "same" in ultimate origin - // or belongs to another/next "same" chunk - if (startOriginLine == -1) { - continue; - } - v.add(startOriginLine); - v.add(startTargetLine); - v.add(c); - c = 0; - startOriginLine = startTargetLine = -1; - // fall-through to check if it's not complete miss but a next chunk + @Experimental(reason="The line-by-line inspector likely to become part of core/command API") + @Callback + public interface LineInspector { + /** + * Not necessarily invoked sequentially by line numbers + */ + void line(int lineNumber, int changesetRevIndex, LineDescriptor ld); + } + + public interface LineDescriptor { + int totalLines(); + } + + /** + * Annotate file revision, line by line. + */ + public static void annotate(HgDataFile df, int changelogRevisionIndex, LineInspector insp) { + if (!df.exists()) { + return; + } + FileAnnotation fa = new FileAnnotation(insp); + AnnotateFacility af = new AnnotateFacility(); + af.annotate(df, changelogRevisionIndex, fa, HgIterateDirection.NewToOld); + } + + // blocks deleted in the target, as reported at the previous step + private LinkedList deleted = new LinkedList(); + // blocks deleted in the origin, to become deletions in target at the next step + private LinkedList newDeleted = new LinkedList(); + // keeps of equal blocks, origin to target, from previous step + // XXX smth like IntSliceVector to access triples (or slices of any size, in fact) + // with easy indexing, e.g. #get(sliceIndex, indexWithinSlice) + // and vect.get(7,2) instead of vect.get(7*SIZEOF_SLICE+2) + private IntVector identical = new IntVector(20 * 3, 2 * 3); + // equal blocks of the current iteration, to be recalculated before next step + // to track line number (current target to ultimate target) mapping + private IntVector newIdentical = new IntVector(20 * 3, 2 * 3); + + private boolean[] knownLines; + private final LineInspector delegate; + + public FileAnnotation(LineInspector lineInspector) { + delegate = lineInspector; + } + + public void start(RevisionDescriptor rd) { + if (knownLines == null) { + knownLines = new boolean[rd.target().elementCount()]; + } + } + + // private static void ppp(IntVector v) { + // for (int i = 0; i < v.size(); i+= 3) { + // int len = v.get(i+2); + // System.out.printf("[%d..%d) == [%d..%d); ", v.get(i), v.get(i) + len, v.get(i+1), v.get(i+1) + len); + // } + // System.out.println(); + // } + + public void done(RevisionDescriptor rd) { + if (identical.size() > 0) { + // update line numbers of the intermediate target to point to ultimate target's line numbers + IntVector v = new IntVector(identical.size(), 2 * 3); + for (int i = 0; i < newIdentical.size(); i += 3) { + int originLine = newIdentical.get(i); + int targetLine = newIdentical.get(i + 1); + int length = newIdentical.get(i + 2); + int startTargetLine = -1, startOriginLine = -1, c = 0; + for (int j = 0; j < length; j++) { + int lnInFinal = mapLineIndex(targetLine + j); + if (lnInFinal == -1 || (startTargetLine != -1 && lnInFinal != startTargetLine + c)) { + // the line is not among "same" in ultimate origin + // or belongs to another/next "same" chunk + if (startOriginLine == -1) { + continue; } - if (lnInFinal != -1) { - if (startOriginLine == -1) { - startOriginLine = originLine + j; - startTargetLine = lnInFinal; - c = 1; - } else { - assert lnInFinal == startTargetLine + c; - c++; - } - } - } - if (startOriginLine != -1) { - assert c > 0; v.add(startOriginLine); v.add(startTargetLine); v.add(c); + c = 0; + startOriginLine = startTargetLine = -1; + // fall-through to check if it's not complete miss but a next chunk + } + if (lnInFinal != -1) { + if (startOriginLine == -1) { + startOriginLine = originLine + j; + startTargetLine = lnInFinal; + c = 1; + } else { + assert lnInFinal == startTargetLine + c; + c++; + } } } - newIdentical.clear(); - identical = v; - } else { - IntVector li = newIdentical; - newIdentical = identical; - identical = li; - } - LinkedList ld = newDeleted; - deleted.clear(); - newDeleted = deleted; - deleted = ld; - } - - public void same(EqualBlock block) { - newIdentical.add(block.originStart()); - newIdentical.add(block.targetStart()); - newIdentical.add(block.length()); - } - - public void added(AddBlock block) { - for (int i = 0, ln = block.firstAddedLine(), x = block.totalAddedLines(); i < x; i++, ln++) { - int lnInFinal = mapLineIndex(ln); - if (lnInFinal != -1 && !knownLines[lnInFinal]) { - delegate.line(lnInFinal, block.targetChangesetIndex(), new LineDescriptor()); - knownLines[lnInFinal] = true; + if (startOriginLine != -1) { + assert c > 0; + v.add(startOriginLine); + v.add(startTargetLine); + v.add(c); } } + newIdentical.clear(); + identical = v; + } else { + IntVector li = newIdentical; + newIdentical = identical; + identical = li; } - - public void changed(ChangeBlock block) { - deleted(block); - added(block); + LinkedList ld = newDeleted; + deleted.clear(); + newDeleted = deleted; + deleted = ld; + } + + public void same(EqualBlock block) { + newIdentical.add(block.originStart()); + newIdentical.add(block.targetStart()); + newIdentical.add(block.length()); + } + + public void added(AddBlock block) { + for (int i = 0, ln = block.firstAddedLine(), x = block.totalAddedLines(); i < x; i++, ln++) { + int lnInFinal = mapLineIndex(ln); + if (lnInFinal != -1 && !knownLines[lnInFinal]) { + delegate.line(lnInFinal, block.targetChangesetIndex(), new LineDescriptorImpl()); + knownLines[lnInFinal] = true; + } + } + } + + public void changed(ChangeBlock block) { + deleted(block); + added(block); + } + + public void deleted(DeleteBlock block) { + newDeleted.add(block); + } + + // line - index in the target + private boolean isDeleted(int line) { + for (DeleteBlock b : deleted) { + if (b.firstRemovedLine() > line) { + break; + } + // line >= b.firstRemovedLine + if (b.firstRemovedLine() + b.totalRemovedLines() > line) { + return true; + } + } + return false; + } + + // map target lines to the lines of the revision being annotated (the one that came first) + private int mapLineIndex(int ln) { + if (isDeleted(ln)) { + return -1; + } + if (identical.isEmpty()) { + return ln; + } + for (int i = 0; i < identical.size(); i += 3) { + final int originStart = identical.get(i); + if (originStart > ln) { + // assert false; + return -1; + } + // ln >= b.originStart + final int length = identical.get(i + 2); + if (originStart + length > ln) { + int targetStart = identical.get(i + 1); + return targetStart + (ln - originStart); + } + } + // assert false; + return -1; + } + + private final class LineDescriptorImpl implements LineDescriptor { + LineDescriptorImpl() { } - public void deleted(DeleteBlock block) { - newDeleted.add(block); - } - - // line - index in the target - private boolean isDeleted(int line) { - for (DeleteBlock b : deleted) { - if (b.firstRemovedLine() > line) { - break; - } - // line >= b.firstRemovedLine - if (b.firstRemovedLine() + b.totalRemovedLines() > line) { - return true; - } - } - return false; + public int totalLines() { + return FileAnnotation.this.knownLines.length; } - - // map target lines to the lines of the revision being annotated (the one that came first) - private int mapLineIndex(int ln) { - if (isDeleted(ln)) { - return -1; - } - if (identical.isEmpty()) { - return ln; - } - for (int i = 0; i < identical.size(); i += 3) { - final int originStart = identical.get(i); - if (originStart > ln) { -// assert false; - return -1; - } - // ln >= b.originStart - final int length = identical.get(i+2); - if (originStart + length > ln) { - int targetStart = identical.get(i+1); - return targetStart + (ln - originStart); - } - } -// assert false; - return -1; - } - - private final class LineDescriptor implements AnnotateFacility.LineDescriptor { - LineDescriptor() { - } - - public int totalLines() { - return FileAnnotation.this.knownLines.length; - } - } - } \ No newline at end of file + } +} \ No newline at end of file diff -r a5fd757d1b5d -r e623aa2ca526 test/org/tmatesoft/hg/test/TestBlame.java --- a/test/org/tmatesoft/hg/test/TestBlame.java Thu Feb 21 21:53:55 2013 +0100 +++ b/test/org/tmatesoft/hg/test/TestBlame.java Fri Feb 22 19:03:25 2013 +0100 @@ -33,14 +33,16 @@ import org.junit.Test; import org.tmatesoft.hg.core.HgIterateDirection; import org.tmatesoft.hg.internal.AnnotateFacility; -import org.tmatesoft.hg.internal.IntVector; import org.tmatesoft.hg.internal.AnnotateFacility.AddBlock; import org.tmatesoft.hg.internal.AnnotateFacility.Block; import org.tmatesoft.hg.internal.AnnotateFacility.BlockData; import org.tmatesoft.hg.internal.AnnotateFacility.ChangeBlock; import org.tmatesoft.hg.internal.AnnotateFacility.DeleteBlock; import org.tmatesoft.hg.internal.AnnotateFacility.EqualBlock; -import org.tmatesoft.hg.internal.AnnotateFacility.LineDescriptor; +import org.tmatesoft.hg.internal.FileAnnotation; +import org.tmatesoft.hg.internal.FileAnnotation.LineDescriptor; +import org.tmatesoft.hg.internal.FileAnnotation.LineInspector; +import org.tmatesoft.hg.internal.IntVector; import org.tmatesoft.hg.repo.HgDataFile; import org.tmatesoft.hg.repo.HgLookup; import org.tmatesoft.hg.repo.HgRepository; @@ -63,7 +65,7 @@ final int checkChangeset = 539; HgDataFile df = repo.getFileNode(fname); ByteArrayOutputStream bos = new ByteArrayOutputStream(); - new AnnotateFacility().annotateChange(df, checkChangeset, new DiffOutInspector(new PrintStream(bos))); + new AnnotateFacility().annotateSingleRevision(df, checkChangeset, new DiffOutInspector(new PrintStream(bos))); LineGrepOutputParser gp = new LineGrepOutputParser("^@@.+"); ExecHelper eh = new ExecHelper(gp, null); eh.run("hg", "diff", "-c", String.valueOf(checkChangeset), "-U", "0", fname); @@ -83,7 +85,7 @@ for (int startChangeset : new int[] { 539, 541 /*, TIP */}) { FileAnnotateInspector fa = new FileAnnotateInspector(); - new AnnotateFacility().annotate(df, startChangeset, fa); + FileAnnotation.annotate(df, startChangeset, fa); op.reset(); @@ -159,18 +161,18 @@ AnnotateFacility af = new AnnotateFacility(); DiffOutInspector dump = new DiffOutInspector(System.out); System.out.println("541 -> 543"); - af.annotateChange(df, 543, dump); + af.annotateSingleRevision(df, 543, dump); System.out.println("539 -> 541"); - af.annotateChange(df, 541, dump); + af.annotateSingleRevision(df, 541, dump); System.out.println("536 -> 539"); - af.annotateChange(df, checkChangeset, dump); + af.annotateSingleRevision(df, checkChangeset, dump); System.out.println("531 -> 536"); - af.annotateChange(df, 536, dump); + af.annotateSingleRevision(df, 536, dump); System.out.println(" -1 -> 531"); - af.annotateChange(df, 531, dump); + af.annotateSingleRevision(df, 531, dump); FileAnnotateInspector fai = new FileAnnotateInspector(); - af.annotate(df, 541, fai); + FileAnnotation.annotate(df, 541, fai); for (int i = 0; i < fai.lineRevisions.length; i++) { System.out.printf("%3d: LINE %d\n", fai.lineRevisions[i], i+1); } @@ -207,7 +209,7 @@ af.annotate(df, TIP, new LineDumpInspector(false), HgIterateDirection.NewToOld); System.out.println(); FileAnnotateInspector fa = new FileAnnotateInspector(); - af.annotate(df, TIP, fa); + FileAnnotation.annotate(df, TIP, fa); for (int i = 0; i < fa.lineRevisions.length; i++) { System.out.printf("%d: LINE %d\n", fa.lineRevisions[i], i+1); } @@ -309,7 +311,7 @@ } } - private static class FileAnnotateInspector implements AnnotateFacility.LineInspector { + private static class FileAnnotateInspector implements LineInspector { private int[] lineRevisions; FileAnnotateInspector() {