# HG changeset patch # User Artem Tikhomirov # Date 1295730684 -3600 # Node ID 0e499fed9b3d8f508ab2ea037b49b514444eb535 # Parent 64bddc2dcc0e93c4fd2d953c124e739ed735654f StatusCommand with tests. Extra constants to indicate common revision cases diff -r 64bddc2dcc0e -r 0e499fed9b3d src/com/tmate/hgkit/ll/HgRepository.java --- a/src/com/tmate/hgkit/ll/HgRepository.java Fri Jan 21 19:21:43 2011 +0100 +++ b/src/com/tmate/hgkit/ll/HgRepository.java Sat Jan 22 22:11:24 2011 +0100 @@ -14,6 +14,8 @@ public abstract class HgRepository { public static final int TIP = -1; + public static final int BAD_REVISION = Integer.MIN_VALUE; + public static final int WORKING_COPY = -2; // temp aux marker method public static IllegalStateException notImplemented() { diff -r 64bddc2dcc0e -r 0e499fed9b3d src/com/tmate/hgkit/ll/StatusCollector.java --- a/src/com/tmate/hgkit/ll/StatusCollector.java Fri Jan 21 19:21:43 2011 +0100 +++ b/src/com/tmate/hgkit/ll/StatusCollector.java Sat Jan 22 22:11:24 2011 +0100 @@ -3,6 +3,9 @@ */ package com.tmate.hgkit.ll; +import static com.tmate.hgkit.ll.HgRepository.BAD_REVISION; +import static com.tmate.hgkit.ll.HgRepository.TIP; + import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -26,7 +29,7 @@ cache = new HashMap(); ManifestRevisionInspector emptyFakeState = new ManifestRevisionInspector(-1, -1); emptyFakeState.begin(-1, null); - emptyFakeState.end(-1); + emptyFakeState.end(-1); // FIXME HgRepo.TIP == -1 as well, need to distinguish fake "prior to first" revision from "the very last" cache.put(-1, emptyFakeState); } @@ -68,6 +71,12 @@ if (inspector instanceof Record) { ((Record) inspector).init(rev1, rev2, this); } + if (rev1 == TIP) { + rev1 = repo.getManifest().getRevisionCount() - 1; + } + if (rev2 == TIP) { + rev2 = repo.getManifest().getRevisionCount() - 1; // XXX add Revlog.tip() func ? + } // in fact, rev1 and rev2 are often next (or close) to each other, // thus, we can optimize Manifest reads here (manifest.walk(rev1, rev2)) ManifestRevisionInspector r1, r2; @@ -145,12 +154,18 @@ } public Nodeid nodeidBeforeChange(String fname) { + if (statusHelper == null || startRev == BAD_REVISION) { + return null; + } if ((modified == null || !modified.contains(fname)) && (removed == null || !removed.contains(fname))) { return null; } return statusHelper.raw(startRev).nodeid(startRev, fname); } public Nodeid nodeidAfterChange(String fname) { + if (statusHelper == null || endRev == BAD_REVISION) { + return null; + } if ((modified == null || !modified.contains(fname)) && (added == null || !added.contains(fname))) { return null; } diff -r 64bddc2dcc0e -r 0e499fed9b3d src/com/tmate/hgkit/ll/WorkingCopyStatusCollector.java --- a/src/com/tmate/hgkit/ll/WorkingCopyStatusCollector.java Fri Jan 21 19:21:43 2011 +0100 +++ b/src/com/tmate/hgkit/ll/WorkingCopyStatusCollector.java Sat Jan 22 22:11:24 2011 +0100 @@ -3,6 +3,7 @@ */ package com.tmate.hgkit.ll; +import static com.tmate.hgkit.ll.HgRepository.BAD_REVISION; import static com.tmate.hgkit.ll.HgRepository.TIP; import java.io.BufferedInputStream; @@ -54,7 +55,13 @@ public void walk(int baseRevision, StatusCollector.Inspector inspector) { final HgIgnore hgIgnore = ((LocalHgRepo) repo).loadIgnore(); // FIXME hack TreeSet knownEntries = getDirstate().all(); - final boolean isTipBase = baseRevision == TIP || baseRevision == repo.getManifest().getRevisionCount(); + final boolean isTipBase; + if (baseRevision == TIP) { + baseRevision = repo.getManifest().getRevisionCount() - 1; + isTipBase = true; + } else { + isTipBase = baseRevision == repo.getManifest().getRevisionCount() - 1; + } StatusCollector.ManifestRevisionInspector collect = null; Set baseRevFiles = Collections.emptySet(); if (!isTipBase) { @@ -66,6 +73,10 @@ } baseRevFiles = new TreeSet(collect.files(baseRevision)); } + if (inspector instanceof StatusCollector.Record) { + StatusCollector sc = baseRevisionCollector == null ? new StatusCollector(repo) : baseRevisionCollector; + ((StatusCollector.Record) inspector).init(baseRevision, BAD_REVISION, sc); + } repoWalker.reset(); while (repoWalker.hasNext()) { repoWalker.next(); diff -r 64bddc2dcc0e -r 0e499fed9b3d src/org/tmatesoft/hg/core/StatusCommand.java --- a/src/org/tmatesoft/hg/core/StatusCommand.java Fri Jan 21 19:21:43 2011 +0100 +++ b/src/org/tmatesoft/hg/core/StatusCommand.java Sat Jan 22 22:11:24 2011 +0100 @@ -16,9 +16,19 @@ */ package org.tmatesoft.hg.core; +import static com.tmate.hgkit.ll.HgRepository.BAD_REVISION; +import static com.tmate.hgkit.ll.HgRepository.TIP; +import static com.tmate.hgkit.ll.HgRepository.WORKING_COPY; + import org.tmatesoft.hg.core.Path.Matcher; +import org.tmatesoft.hg.util.PathPool; +import com.tmate.hgkit.fs.FileWalker; import com.tmate.hgkit.ll.HgRepository; +import com.tmate.hgkit.ll.LocalHgRepo; +import com.tmate.hgkit.ll.StatusCollector; +import com.tmate.hgkit.ll.WorkingCopyStatusCollector; +import com.tmate.hgkit.ll.StatusCollector.Record; /** * @@ -28,22 +38,55 @@ public class StatusCommand { private final HgRepository repo; - private boolean needClean = false; - private boolean needIgnored = false; + private boolean needModified; + private boolean needAdded; + private boolean needRemoved; + private boolean needUnknown; + private boolean needMissing; + private boolean needClean; + private boolean needIgnored; private Matcher matcher; - private int startRevision; - private Integer endRevision; // need three states, set, -1 or actual rev number + private int startRevision = TIP; + private int endRevision = WORKING_COPY; private boolean visitSubRepo = true; - public StatusCommand(HgRepository hgRepo) { - this.repo = hgRepo; + public StatusCommand(HgRepository hgRepo) { + repo = hgRepo; + defaults(); } - public StatusCommand all() { - needClean = true; + public StatusCommand defaults() { + needModified = needAdded = needRemoved = needUnknown = needMissing = true; + needClean = needIgnored = false; return this; } + public StatusCommand all() { + needModified = needAdded = needRemoved = needUnknown = needMissing = true; + needClean = needIgnored = true; + return this; + } + + public StatusCommand modified(boolean include) { + needModified = include; + return this; + } + public StatusCommand added(boolean include) { + needAdded = include; + return this; + } + public StatusCommand removed(boolean include) { + needRemoved = include; + return this; + } + public StatusCommand deleted(boolean include) { + needMissing = include; + return this; + } + public StatusCommand unknown(boolean include) { + needUnknown = include; + return this; + } public StatusCommand clean(boolean include) { needClean = include; return this; @@ -53,17 +96,36 @@ return this; } - // if set, either base:revision or base:workingdir + /** + * if set, either base:revision or base:workingdir + * to unset, pass {@link HgRepository#TIP} or {@link HgRepository#BAD_REVISION} + * @param revision + * @return + */ + public StatusCommand base(int revision) { + if (revision == WORKING_COPY) { + throw new IllegalArgumentException(); + } + if (revision == BAD_REVISION) { + revision = TIP; + } startRevision = revision; return this; } - // revision without base == --change + /** + * Revision without base == --change + * Pass {@link HgRepository#WORKING_COPY} or {@link HgRepository#BAD_REVISION} to reset + * @param revision + * @return + */ public StatusCommand revision(int revision) { - // XXX how to clear endRevision, if needed. - // Perhaps, use of WC_REVISION or BAD_REVISION == -2 or Int.MIN_VALUE? - endRevision = new Integer(revision); + if (revision == BAD_REVISION) { + revision = WORKING_COPY; + } + // XXX negative values, except for predefined constants, shall throw IAE. + endRevision = revision; return this; } @@ -77,7 +139,21 @@ throw HgRepository.notImplemented(); } - public void execute() { - throw HgRepository.notImplemented(); + public void execute(StatusCollector.Inspector inspector) { + StatusCollector sc = new StatusCollector(repo); // TODO from CommandContext +// StatusCollector.Record r = new StatusCollector.Record(); // XXX use own inspector not to collect entries that + // are not interesting or do not match name + if (endRevision == WORKING_COPY) { + WorkingCopyStatusCollector wcsc = new WorkingCopyStatusCollector(repo, ((LocalHgRepo) repo).createWorkingDirWalker()); + wcsc.setBaseRevisionCollector(sc); + wcsc.walk(startRevision, inspector); + } else { + if (startRevision == TIP) { + sc.change(endRevision, inspector); + } else { + sc.walk(startRevision, endRevision, inspector); + } + } +// PathPool pathHelper = new PathPool(repo.getPathHelper()); // TODO from CommandContext } } diff -r 64bddc2dcc0e -r 0e499fed9b3d test/org/tmatesoft/hg/test/TestStatus.java --- a/test/org/tmatesoft/hg/test/TestStatus.java Fri Jan 21 19:21:43 2011 +0100 +++ b/test/org/tmatesoft/hg/test/TestStatus.java Sat Jan 22 22:11:24 2011 +0100 @@ -16,11 +16,15 @@ */ package org.tmatesoft.hg.test; +import static com.tmate.hgkit.ll.HgRepository.TIP; + import java.io.File; import java.util.Collection; import java.util.LinkedList; import java.util.List; +import org.tmatesoft.hg.core.StatusCommand; + import com.tmate.hgkit.fs.FileWalker; import com.tmate.hgkit.fs.RepositoryLookup; import com.tmate.hgkit.ll.HgRepository; @@ -34,9 +38,9 @@ */ public class TestStatus { + private final HgRepository repo; private StatusOutputParser statusParser; private ExecHelper eh; - private final HgRepository repo; public static void main(String[] args) throws Exception { HgRepository repo = new RepositoryLookup().detectFromWorkingDir(); @@ -53,6 +57,7 @@ public void testLowLevel() throws Exception { final WorkingCopyStatusCollector wcc = new WorkingCopyStatusCollector(repo, new FileWalker(new File(System.getProperty("user.dir")))); + statusParser.reset(); eh.run("hg", "status", "-A"); StatusCollector.Record r = wcc.status(HgRepository.TIP); report("hg status -A", r, statusParser); @@ -71,7 +76,25 @@ } public void testStatusCommand() throws Exception { - throw HgRepository.notImplemented(); + final StatusCommand sc = new StatusCommand(repo).all(); + StatusCollector.Record r; + statusParser.reset(); + eh.run("hg", "status", "-A"); + sc.execute(r = new StatusCollector.Record()); + report("hg status -A", r, statusParser); + // + statusParser.reset(); + int revision = 3; + eh.run("hg", "status", "-A", "--rev", String.valueOf(revision)); + sc.base(revision).execute(r = new StatusCollector.Record()); + report("status -A --rev " + revision, r, statusParser); + // + statusParser.reset(); + eh.run("hg", "status", "-A", "--change", String.valueOf(revision)); + sc.base(TIP).revision(revision).execute(r = new StatusCollector.Record()); + report("status -A --change " + revision, r, statusParser); + + // TODO check not -A, but defaults()/custom set of modifications } private static void report(String what, StatusCollector.Record r, StatusOutputParser statusParser) {