Mercurial > hg4j
diff src/org/tmatesoft/hg/internal/AnnotateFacility.java @ 548:ab21ac7dd833
Line-by-line annotation API and support code in place
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Mon, 18 Feb 2013 19:58:51 +0100 |
parents | cd78e8b9d7bc |
children | 83afa680555d |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/internal/AnnotateFacility.java Mon Feb 18 19:58:10 2013 +0100 +++ b/src/org/tmatesoft/hg/internal/AnnotateFacility.java Mon Feb 18 19:58:51 2013 +0100 @@ -17,11 +17,13 @@ package org.tmatesoft.hg.internal; import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; +import static org.tmatesoft.hg.repo.HgRepository.TIP; import org.tmatesoft.hg.core.Nodeid; import org.tmatesoft.hg.internal.PatchGenerator.LineSequence; import org.tmatesoft.hg.repo.HgDataFile; import org.tmatesoft.hg.repo.HgInvalidStateException; +import org.tmatesoft.hg.repo.HgRepository; import org.tmatesoft.hg.util.CancelledException; /** @@ -31,7 +33,27 @@ */ @Experimental(reason="work in progress") public class AnnotateFacility { - + + /** + * Annotate file revision, line by line. + */ + public void annotate(HgDataFile df, int changesetRevisionIndex, LineInspector insp) { + if (!df.exists()) { + return; + } + Nodeid fileRev = df.getRepo().getManifest().getFileRevision(changesetRevisionIndex, df.getPath()); + int fileRevIndex = df.getRevisionIndex(fileRev); + int[] fileRevParents = new int[2]; + FileAnnotation fa = new FileAnnotation(insp); + do { + // also covers changesetRevisionIndex == TIP, #implAnnotateChange doesn't tolerate constants + changesetRevisionIndex = df.getChangesetRevisionIndex(fileRevIndex); + df.parents(fileRevIndex, fileRevParents, null, null); + implAnnotateChange(df, changesetRevisionIndex, fileRevIndex, fileRevParents, fa); + fileRevIndex = fileRevParents[0]; + } while (fileRevIndex != NO_REVISION); + } + /** * Annotates changes of the file against its parent(s) */ @@ -41,22 +63,29 @@ int fileRevIndex = df.getRevisionIndex(fileRev); int[] fileRevParents = new int[2]; df.parents(fileRevIndex, fileRevParents, null, null); + if (changesetRevisionIndex == TIP) { + changesetRevisionIndex = df.getChangesetRevisionIndex(fileRevIndex); + } + implAnnotateChange(df, changesetRevisionIndex, fileRevIndex, fileRevParents, insp); + } + + private void implAnnotateChange(HgDataFile df, int csetRevIndex, int fileRevIndex, int[] fileParentRevs, BlockInspector insp) { try { - if (fileRevParents[0] != NO_REVISION && fileRevParents[1] != NO_REVISION) { + if (fileParentRevs[0] != NO_REVISION && fileParentRevs[1] != NO_REVISION) { // merge - } else if (fileRevParents[0] == fileRevParents[1]) { + } else if (fileParentRevs[0] == fileParentRevs[1]) { // may be equal iff both are unset - assert fileRevParents[0] == NO_REVISION; + assert fileParentRevs[0] == NO_REVISION; // everything added ByteArrayChannel c; df.content(fileRevIndex, c = new ByteArrayChannel()); - BlameBlockInspector bbi = new BlameBlockInspector(insp, NO_REVISION, changesetRevisionIndex); + BlameBlockInspector bbi = new BlameBlockInspector(insp, NO_REVISION, csetRevIndex); LineSequence cls = LineSequence.newlines(c.toArray()); bbi.begin(LineSequence.newlines(new byte[0]), cls); bbi.match(0, cls.chunkCount()-1, 0); bbi.end(); } else { - int soleParent = fileRevParents[0] == NO_REVISION ? fileRevParents[1] : fileRevParents[0]; + int soleParent = fileParentRevs[0] == NO_REVISION ? fileParentRevs[1] : fileParentRevs[0]; assert soleParent != NO_REVISION; ByteArrayChannel c1, c2; df.content(soleParent, c1 = new ByteArrayChannel()); @@ -64,7 +93,7 @@ int parentChangesetRevIndex = df.getChangesetRevisionIndex(soleParent); PatchGenerator<LineSequence> pg = new PatchGenerator<LineSequence>(); pg.init(LineSequence.newlines(c1.toArray()), LineSequence.newlines(c2.toArray())); - pg.findMatchingBlocks(new BlameBlockInspector(insp, parentChangesetRevIndex, changesetRevisionIndex)); + pg.findMatchingBlocks(new BlameBlockInspector(insp, parentChangesetRevIndex, csetRevIndex)); } } catch (CancelledException ex) { // TODO likely it was bad idea to throw cancelled exception from content() @@ -123,6 +152,9 @@ @Callback public interface LineInspector { + /** + * Not necessarily invoked sequentially by line numbers + */ void line(int lineNumber, int changesetRevIndex, LineDescriptor ld); }