Mercurial > hg4j
changeset 507:a6435c1a42d0
Test for HgChangesetTreeHandler - make sure nothing is broken prior to adding --follow support
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Wed, 12 Dec 2012 14:17:12 +0100 |
parents | 27398bbfd543 |
children | ca5202afea90 |
files | cmdline/org/tmatesoft/hg/console/Main.java src/org/tmatesoft/hg/core/HgChangesetTreeHandler.java src/org/tmatesoft/hg/core/HgLogCommand.java test/org/tmatesoft/hg/test/TestHistory.java |
diffstat | 4 files changed, 113 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/cmdline/org/tmatesoft/hg/console/Main.java Fri Nov 30 22:52:39 2012 +0100 +++ b/cmdline/org/tmatesoft/hg/console/Main.java Wed Dec 12 14:17:12 2012 +0100 @@ -96,11 +96,11 @@ public static void main(String[] args) throws Exception { Main m = new Main(args); - m.tryExtensions(); +// m.tryExtensions(); // m.dumpBookmarks(); // m.readConfigFile(); // m.dumpCommitLastMessage(); -// m.buildFileLog(); + m.buildFileLog(); // m.testConsoleLog(); // m.testTreeTraversal(); // m.testRevisionMap();
--- a/src/org/tmatesoft/hg/core/HgChangesetTreeHandler.java Fri Nov 30 22:52:39 2012 +0100 +++ b/src/org/tmatesoft/hg/core/HgChangesetTreeHandler.java Wed Dec 12 14:17:12 2012 +0100 @@ -47,7 +47,7 @@ public Nodeid fileRevision(); /** - * @return changeset associated with the current revision + * @return changeset associated with the current file revision */ public HgChangeset changeset(); @@ -58,7 +58,26 @@ public Nodeid changesetRevision(); /** - * Node, these are not necessarily in direct relation to parents of changeset from {@link #changeset()} + * Identifies parent changes, changesets where file/revlog in question was modified prior to change being visited. + * + * Note, these are not necessarily in direct relation to parents of changeset from {@link #changeset()} + * + * Imagine next history (grows from bottom to top): + * <pre> + * o A o + * | \ | + * o B \/ + * | o C + * | / + * o / + * | / + * o D + * </pre> + * + * When we are at {@link TreeElement} for <code>A</code>, <code>B</code> and <code>C</code> are changeset parents, naturally. However + * if the file/revlog we've been walking has not been changed in <code>B</code> and <code>C</code>, but e.g. in <code>D</code> only, + * then this {@link #parents()} call would return pair with single element only, pointing to <code>D</code> + * * @return changesets that correspond to parents of the current file node, either pair element may be <code>null</code>. */ public Pair<HgChangeset, HgChangeset> parents();
--- a/src/org/tmatesoft/hg/core/HgLogCommand.java Fri Nov 30 22:52:39 2012 +0100 +++ b/src/org/tmatesoft/hg/core/HgLogCommand.java Wed Dec 12 14:17:12 2012 +0100 @@ -330,36 +330,65 @@ } }; final ProgressSupport progressHelper = getProgressSupport(handler); - progressHelper.start(4); final CancelSupport cancelHelper = getCancelSupport(handler, true); - cancelHelper.checkCancelled(); - HgDataFile fileNode = repo.getFileNode(file); - // build tree of nodes according to parents in file's revlog - final TreeBuildInspector treeBuildInspector = new TreeBuildInspector(); - final HistoryNode[] completeHistory = treeBuildInspector.go(fileNode); - progressHelper.worked(1); - cancelHelper.checkCancelled(); - ElementImpl ei = new ElementImpl(treeBuildInspector.commitRevisions.length); - final ProgressSupport ph2; - if (treeBuildInspector.commitRevisions.length < 100 /*XXX is it really worth it? */) { - ei.initTransform(); - repo.getChangelog().range(ei, treeBuildInspector.commitRevisions); + + LinkedList<HgDataFile> fileRenamesQueue = buildFileRenamesQueue(); + progressHelper.start(4 * fileRenamesQueue.size()); + do { + HgDataFile fileNode = fileRenamesQueue.removeLast(); + cancelHelper.checkCancelled(); + // build tree of nodes according to parents in file's revlog + final TreeBuildInspector treeBuildInspector = new TreeBuildInspector(); + final HistoryNode[] completeHistory = treeBuildInspector.go(fileNode); progressHelper.worked(1); - ph2 = new ProgressSupport.Sub(progressHelper, 2); - } else { - ph2 = new ProgressSupport.Sub(progressHelper, 3); - } - ph2.start(completeHistory.length); - // XXX shall sort completeHistory according to changeset numbers? - for (int i = 0; i < completeHistory.length; i++ ) { - final HistoryNode n = completeHistory[i]; - handler.treeElement(ei.init(n)); - ph2.worked(1); cancelHelper.checkCancelled(); - } + ElementImpl ei = new ElementImpl(treeBuildInspector.commitRevisions.length); + final ProgressSupport ph2; + if (treeBuildInspector.commitRevisions.length < 100 /*XXX is it really worth it? */) { + ei.initTransform(); + repo.getChangelog().range(ei, treeBuildInspector.commitRevisions); + progressHelper.worked(1); + ph2 = new ProgressSupport.Sub(progressHelper, 2); + } else { + ph2 = new ProgressSupport.Sub(progressHelper, 3); + } + ph2.start(completeHistory.length); + // XXX shall sort completeHistory according to changeset numbers? + for (int i = 0; i < completeHistory.length; i++ ) { + final HistoryNode n = completeHistory[i]; + handler.treeElement(ei.init(n)); + ph2.worked(1); + cancelHelper.checkCancelled(); + } + } while (!fileRenamesQueue.isEmpty()); progressHelper.done(); } + /** + * Follows file renames and build a list of all corresponding file nodes. If {@link #followHistory} is <code>false</code>, + * the list contains one element only, file node with the name of the file as it was specified by the user. + * + * @return list of file renames, with most recent file first + */ + private LinkedList<HgDataFile> buildFileRenamesQueue() { + LinkedList<HgDataFile> rv = new LinkedList<HgDataFile>(); + if (!followHistory) { + rv.add(repo.getFileNode(file)); + return rv; + } + HgDataFile fileNode; + Path fp = file; + boolean isCopy; + do { + fileNode = repo.getFileNode(fp); + rv.addLast(fileNode); + if (isCopy = fileNode.isCopy()) { + fp = fileNode.getCopySourceName(); + } + } while (isCopy); + return rv; + } + // public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) {
--- a/test/org/tmatesoft/hg/test/TestHistory.java Fri Nov 30 22:52:39 2012 +0100 +++ b/test/org/tmatesoft/hg/test/TestHistory.java Wed Dec 12 14:17:12 2012 +0100 @@ -29,14 +29,18 @@ import org.junit.Rule; import org.junit.Test; +import org.tmatesoft.hg.core.HgCallbackTargetException; import org.tmatesoft.hg.core.HgChangeset; import org.tmatesoft.hg.core.HgChangesetHandler; +import org.tmatesoft.hg.core.HgChangesetTreeHandler; import org.tmatesoft.hg.core.HgFileRevision; import org.tmatesoft.hg.core.HgLogCommand; import org.tmatesoft.hg.core.HgLogCommand.CollectHandler; +import org.tmatesoft.hg.core.Nodeid; import org.tmatesoft.hg.repo.HgLookup; import org.tmatesoft.hg.repo.HgRepository; import org.tmatesoft.hg.test.LogOutputParser.Record; +import org.tmatesoft.hg.util.Pair; import org.tmatesoft.hg.util.Path; @@ -118,6 +122,39 @@ }); report(what, sorted, false); } + + @Test + public void testChangesetTree() throws Exception { + repo = Configuration.get().find("branches-1"); + final String fname = "file1"; + assertTrue("[sanity]", repo.getFileNode(fname).exists()); + eh.run("hg", "log", "--debug", fname, "--cwd", repo.getLocation()); + + final LinkedList<HgChangeset> cmdResult = new LinkedList<HgChangeset>(); + new HgLogCommand(repo).file(fname, false).execute(new HgChangesetTreeHandler() { + + public void treeElement(TreeElement entry) throws HgCallbackTargetException { + // check consistency + Nodeid cset = entry.changeset().getNodeid(); + errorCollector.assertEquals(entry.changesetRevision(), cset); + Pair<HgChangeset, HgChangeset> parents_a = entry.parents(); + Pair<Nodeid, Nodeid> parents_b = entry.parentRevisions(); + if (parents_b.first().isNull()) { + errorCollector.assertTrue(parents_a.first() == null); + } else { + errorCollector.assertEquals(parents_b.first(), parents_a.first().getNodeid()); + } + if (parents_b.second().isNull()) { + errorCollector.assertTrue(parents_a.second() == null); + } else { + errorCollector.assertEquals(parents_b.second(), parents_a.second().getNodeid()); + } + // + cmdResult.add(entry.changeset()); + } + }); + report("execute with HgChangesetTreeHandler", cmdResult, true); + } private void report(String what, List<HgChangeset> r, boolean reverseConsoleResult) { final List<Record> consoleResult = changelogParser.getResult();