# HG changeset patch # User Artem Tikhomirov # Date 1365520530 -7200 # Node ID 78a9e26e670d5fbbf53fdf13bb82ffab6e4910be # Parent e6407313bab71a1def058da46bcb3721592cc044 Refactor common code to initialize changelog revision for a command into standalone class diff -r e6407313bab7 -r 78a9e26e670d src/org/tmatesoft/hg/core/HgCatCommand.java --- a/src/org/tmatesoft/hg/core/HgCatCommand.java Wed Apr 03 21:28:06 2013 +0200 +++ b/src/org/tmatesoft/hg/core/HgCatCommand.java Tue Apr 09 17:15:30 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 TMate Software Ltd + * Copyright (c) 2011-2013 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -125,6 +125,7 @@ revisionIndex = BAD_REVISION; revision = null; cset = nodeid; + // TODO [2.0 API break] shall use CsetParamKeeper instead, but Exception thrown would break the API return this; } diff -r e6407313bab7 -r 78a9e26e670d src/org/tmatesoft/hg/core/HgCheckoutCommand.java --- a/src/org/tmatesoft/hg/core/HgCheckoutCommand.java Wed Apr 03 21:28:06 2013 +0200 +++ b/src/org/tmatesoft/hg/core/HgCheckoutCommand.java Tue Apr 09 17:15:30 2013 +0200 @@ -25,6 +25,7 @@ import java.io.OutputStreamWriter; import java.nio.channels.FileChannel; +import org.tmatesoft.hg.internal.CsetParamKeeper; import org.tmatesoft.hg.internal.DirstateBuilder; import org.tmatesoft.hg.internal.EncodingHelper; import org.tmatesoft.hg.internal.Experimental; @@ -32,11 +33,10 @@ import org.tmatesoft.hg.internal.WorkingDirFileWriter; import org.tmatesoft.hg.repo.HgDataFile; import org.tmatesoft.hg.repo.HgDirstate; -import org.tmatesoft.hg.repo.HgInternals; -import org.tmatesoft.hg.repo.HgInvalidRevisionException; -import org.tmatesoft.hg.repo.HgManifest; import org.tmatesoft.hg.repo.HgDirstate.EntryKind; import org.tmatesoft.hg.repo.HgDirstate.Record; +import org.tmatesoft.hg.repo.HgInternals; +import org.tmatesoft.hg.repo.HgManifest; import org.tmatesoft.hg.repo.HgManifest.Flags; import org.tmatesoft.hg.repo.HgRepository; import org.tmatesoft.hg.repo.HgRuntimeException; @@ -57,11 +57,12 @@ public class HgCheckoutCommand extends HgAbstractCommand{ private final HgRepository repo; - private int revisionToCheckout = HgRepository.BAD_REVISION; + private final CsetParamKeeper revisionToCheckout; private boolean cleanCheckout; public HgCheckoutCommand(HgRepository hgRepo) { repo = hgRepo; + revisionToCheckout = new CsetParamKeeper(repo); } /** @@ -85,29 +86,19 @@ * @throws HgBadArgumentException if failed to find supplied changeset */ public HgCheckoutCommand changeset(Nodeid nodeid) throws HgBadArgumentException { - try { - return changeset(repo.getChangelog().getRevisionIndex(nodeid)); - } catch (HgInvalidRevisionException ex) { - throw new HgBadArgumentException("Can't find revision", ex).setRevision(nodeid); - } + revisionToCheckout.set(nodeid); + return this; } /** * Select revision to check out using local revision index * - * @param changesetIndex local revision index, or {@link HgRepository#TIP} + * @param changesetIndex local changelog revision index, or {@link HgRepository#TIP} * @return this for convenience * @throws HgBadArgumentException if failed to find supplied changeset */ public HgCheckoutCommand changeset(int changesetIndex) throws HgBadArgumentException { - int lastCsetIndex = repo.getChangelog().getLastRevision(); - if (changesetIndex == HgRepository.TIP) { - changesetIndex = lastCsetIndex; - } - if (changesetIndex < 0 || changesetIndex > lastCsetIndex) { - throw new HgBadArgumentException(String.format("Bad revision index %d, value from [0..%d] expected", changesetIndex, lastCsetIndex), null).setRevisionIndex(changesetIndex); - } - revisionToCheckout = changesetIndex; + revisionToCheckout.set(changesetIndex); return this; } @@ -159,8 +150,10 @@ return true; } }; - dirstateBuilder.parents(repo.getChangelog().getRevision(revisionToCheckout), null); - repo.getManifest().walk(revisionToCheckout, revisionToCheckout, insp); + // checkout tip if no revision set + final int coRevision = revisionToCheckout.get(HgRepository.TIP); + dirstateBuilder.parents(repo.getChangelog().getRevision(coRevision), null); + repo.getManifest().walk(coRevision, coRevision, insp); worker.checkFailed(); File dirstateFile = internalRepo.getRepositoryFile(Dirstate); try { @@ -170,7 +163,7 @@ } catch (IOException ex) { throw new HgIOException("Can't write down new directory state", ex, dirstateFile); } - String branchName = repo.getChangelog().range(revisionToCheckout, revisionToCheckout).get(0).branch(); + String branchName = repo.getChangelog().range(coRevision, coRevision).get(0).branch(); assert branchName != null; if (!HgRepository.DEFAULT_BRANCH_NAME.equals(branchName)) { File branchFile = internalRepo.getRepositoryFile(Branch); diff -r e6407313bab7 -r 78a9e26e670d src/org/tmatesoft/hg/core/HgLogCommand.java --- a/src/org/tmatesoft/hg/core/HgLogCommand.java Wed Apr 03 21:28:06 2013 +0200 +++ b/src/org/tmatesoft/hg/core/HgLogCommand.java Tue Apr 09 17:15:30 2013 +0200 @@ -1,5 +1,5 @@ /* -s * Copyright (c) 2011-2012 TMate Software Ltd +s * Copyright (c) 2011-2013 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,6 +36,7 @@ import org.tmatesoft.hg.internal.AdapterPlug; import org.tmatesoft.hg.internal.BatchRangeHelper; +import org.tmatesoft.hg.internal.CsetParamKeeper; import org.tmatesoft.hg.internal.IntMap; import org.tmatesoft.hg.internal.IntVector; import org.tmatesoft.hg.internal.Internals; @@ -45,7 +46,6 @@ import org.tmatesoft.hg.repo.HgChangelog.RawChangeset; import org.tmatesoft.hg.repo.HgDataFile; import org.tmatesoft.hg.repo.HgInvalidControlFileException; -import org.tmatesoft.hg.repo.HgInvalidRevisionException; import org.tmatesoft.hg.repo.HgInvalidStateException; import org.tmatesoft.hg.repo.HgParentChildMap; import org.tmatesoft.hg.repo.HgRepository; @@ -176,6 +176,7 @@ startRev = rev1; endRev = rev2; } + // TODO [2.0 API break] shall throw HgBadArgumentException, like other commands do return this; } @@ -188,12 +189,8 @@ */ public HgLogCommand changeset(Nodeid nid) throws HgBadArgumentException { // XXX perhaps, shall support multiple (...) arguments and extend #execute to handle not only range, but also set of revisions. - try { - final int csetRevIndex = repo.getChangelog().getRevisionIndex(nid); - return range(csetRevIndex, csetRevIndex); - } catch (HgInvalidRevisionException ex) { - throw new HgBadArgumentException("Can't find revision", ex).setRevision(nid); - } + final int csetRevIndex = new CsetParamKeeper(repo).set(nid).get(); + return range(csetRevIndex, csetRevIndex); } /** diff -r e6407313bab7 -r 78a9e26e670d src/org/tmatesoft/hg/core/HgManifestCommand.java --- a/src/org/tmatesoft/hg/core/HgManifestCommand.java Wed Apr 03 21:28:06 2013 +0200 +++ b/src/org/tmatesoft/hg/core/HgManifestCommand.java Tue Apr 09 17:15:30 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 TMate Software Ltd + * Copyright (c) 2011-2013 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,19 +17,17 @@ package org.tmatesoft.hg.core; import static org.tmatesoft.hg.repo.HgRepository.*; -import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION; -import static org.tmatesoft.hg.repo.HgRepository.TIP; import java.util.ConcurrentModificationException; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; +import org.tmatesoft.hg.internal.CsetParamKeeper; import org.tmatesoft.hg.internal.PathPool; -import org.tmatesoft.hg.repo.HgInvalidRevisionException; import org.tmatesoft.hg.repo.HgManifest; +import org.tmatesoft.hg.repo.HgManifest.Flags; import org.tmatesoft.hg.repo.HgRepository; -import org.tmatesoft.hg.repo.HgManifest.Flags; import org.tmatesoft.hg.repo.HgRuntimeException; import org.tmatesoft.hg.util.CancelSupport; import org.tmatesoft.hg.util.CancelledException; @@ -70,6 +68,7 @@ badArgs |= rev2 != TIP && rev2 < rev1; // range(3, 1); badArgs |= rev1 == TIP && rev2 != TIP; // range(TIP, 2), although this may be legitimate when TIP points to 2 if (badArgs) { + // TODO [2.0 API break] throw checked HgBadArgumentException instead throw new IllegalArgumentException(String.format("Bad range: [%d, %d]", rev1, rev2)); } startRev = rev1; @@ -83,6 +82,7 @@ * @return this for convenience. */ public HgManifestCommand changeset(int csetRevisionIndex) { + // TODO [2.0 API break] shall throw HgBadArgumentException, like other commands do return range(csetRevisionIndex, csetRevisionIndex); } @@ -95,12 +95,8 @@ */ public HgManifestCommand changeset(Nodeid nid) throws HgBadArgumentException { // XXX also see HgLogCommand#changeset(Nodeid) - try { - final int csetRevIndex = repo.getChangelog().getRevisionIndex(nid); - return range(csetRevIndex, csetRevIndex); - } catch (HgInvalidRevisionException ex) { - throw new HgBadArgumentException("Can't find revision", ex).setRevision(nid); - } + final int csetRevIndex = new CsetParamKeeper(repo).set(nid).get(); + return range(csetRevIndex, csetRevIndex); } public HgManifestCommand dirs(boolean include) { diff -r e6407313bab7 -r 78a9e26e670d src/org/tmatesoft/hg/core/HgRevertCommand.java --- a/src/org/tmatesoft/hg/core/HgRevertCommand.java Wed Apr 03 21:28:06 2013 +0200 +++ b/src/org/tmatesoft/hg/core/HgRevertCommand.java Tue Apr 09 17:15:30 2013 +0200 @@ -21,15 +21,15 @@ import java.util.LinkedHashSet; import java.util.Set; +import org.tmatesoft.hg.internal.CsetParamKeeper; import org.tmatesoft.hg.internal.DirstateBuilder; import org.tmatesoft.hg.internal.DirstateReader; import org.tmatesoft.hg.internal.Experimental; import org.tmatesoft.hg.internal.Internals; -import org.tmatesoft.hg.repo.HgInvalidRevisionException; import org.tmatesoft.hg.repo.HgManifest; +import org.tmatesoft.hg.repo.HgManifest.Flags; import org.tmatesoft.hg.repo.HgRepository; import org.tmatesoft.hg.repo.HgRuntimeException; -import org.tmatesoft.hg.repo.HgManifest.Flags; import org.tmatesoft.hg.util.CancelledException; import org.tmatesoft.hg.util.Path; @@ -46,11 +46,13 @@ private final HgRepository repo; private final Set files = new LinkedHashSet(); - private int changesetToCheckout = HgRepository.WORKING_COPY; // XXX WORKING_COPY_PARENT, in fact + private CsetParamKeeper changesetToCheckout; private boolean keepOriginal = true; public HgRevertCommand(HgRepository hgRepo) { repo = hgRepo; + changesetToCheckout = new CsetParamKeeper(hgRepo); + changesetToCheckout.doSet(HgRepository.WORKING_COPY); // XXX WORKING_COPY_PARENT, in fact } /** @@ -72,11 +74,7 @@ * @throws HgBadArgumentException */ public HgRevertCommand changeset(int changesetRevIndex) throws HgBadArgumentException { - int lastCsetIndex = repo.getChangelog().getLastRevision(); - if (changesetRevIndex < 0 || changesetRevIndex > lastCsetIndex) { - throw new HgBadArgumentException(String.format("Bad revision index %d, value from [0..%d] expected", changesetRevIndex, lastCsetIndex), null).setRevisionIndex(changesetRevIndex); - } - changesetToCheckout = changesetRevIndex; + changesetToCheckout.set(changesetRevIndex); return this; } @@ -88,14 +86,11 @@ * @throws HgBadArgumentException */ public HgRevertCommand changeset(Nodeid revision) throws HgBadArgumentException { - try { - return changeset(repo.getChangelog().getRevisionIndex(revision)); - } catch (HgInvalidRevisionException ex) { - throw new HgBadArgumentException("Can't find revision", ex).setRevision(revision); - } + changesetToCheckout.set(revision); + return this; } - // TODO keepOriginal() to save .orig + // TODO keepOriginal() to save .orig (with tests!) /** * Perform the back out for the given files @@ -107,10 +102,10 @@ public void execute() throws HgException, CancelledException { try { final int csetRevision; - if (changesetToCheckout == HgRepository.WORKING_COPY) { + if (changesetToCheckout.get() == HgRepository.WORKING_COPY) { csetRevision = repo.getChangelog().getRevisionIndex(repo.getWorkingCopyParents().first()); } else { - csetRevision = changesetToCheckout; + csetRevision = changesetToCheckout.get(); } Internals implRepo = Internals.getInstance(repo); final DirstateBuilder dirstateBuilder = new DirstateBuilder(implRepo); diff -r e6407313bab7 -r 78a9e26e670d src/org/tmatesoft/hg/internal/CsetParamKeeper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/tmatesoft/hg/internal/CsetParamKeeper.java Tue Apr 09 17:15:30 2013 +0200 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013 TMate Software Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For information on how to redistribute this software under + * the terms of a license other than GNU General Public License + * contact TMate Software at support@hg4j.com + */ +package org.tmatesoft.hg.internal; + +import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION; +import static org.tmatesoft.hg.repo.HgRepository.TIP; + +import org.tmatesoft.hg.core.HgBadArgumentException; +import org.tmatesoft.hg.core.Nodeid; +import org.tmatesoft.hg.repo.HgInvalidRevisionException; +import org.tmatesoft.hg.repo.HgRepository; + +/** + * Common code to keep changelog revision and to perform boundary check. + * + * @author Artem Tikhomirov + * @author TMate Software Ltd. + */ +public class CsetParamKeeper { + private final HgRepository repo; + private int changelogRevisionIndex = HgRepository.BAD_REVISION; + + public CsetParamKeeper(HgRepository hgRepo) { + repo = hgRepo; + } + + public CsetParamKeeper set(Nodeid changeset) throws HgBadArgumentException { + try { + set(repo.getChangelog().getRevisionIndex(changeset)); + } catch (HgInvalidRevisionException ex) { + throw new HgBadArgumentException("Can't find revision", ex).setRevision(changeset); + } + return this; + } + + public CsetParamKeeper set(int changelogRevIndex) throws HgBadArgumentException { + int lastCsetIndex = repo.getChangelog().getLastRevision(); + if (changelogRevIndex == HgRepository.TIP) { + changelogRevIndex = lastCsetIndex; + } + if (changelogRevIndex < 0 || changelogRevIndex > lastCsetIndex) { + throw new HgBadArgumentException(String.format("Bad revision index %d, value from [0..%d] expected", changelogRevIndex, lastCsetIndex), null).setRevisionIndex(changelogRevIndex); + } + doSet(changelogRevIndex); + return this; + } + + public void doSet(int changelogRevIndex) { + changelogRevisionIndex = changelogRevIndex; + } + + /** + * @return the value set, or {@link HgRepository#BAD_REVISION} otherwise + */ + public int get() { + return changelogRevisionIndex; + } + + /** + * @param defaultRevisionIndex value to return when no revision was set, may be {@link HgRepository#TIP} which gets translated to real index if used + * @return changelog revision index if set, or defaultRevisionIndex value otherwise + */ + public int get(int defaultRevisionIndex) { + // XXX perhaps, shall translate other predefined constants (like WORKING COPY) here, too (e.g. for HgRevertCommand) + if (changelogRevisionIndex != BAD_REVISION || changelogRevisionIndex != TIP) { + return changelogRevisionIndex; + } + if (changelogRevisionIndex == TIP || defaultRevisionIndex == TIP) { + return repo.getChangelog().getLastRevision(); + } + return defaultRevisionIndex; + } +} diff -r e6407313bab7 -r 78a9e26e670d test/org/tmatesoft/hg/test/TestCommit.java --- a/test/org/tmatesoft/hg/test/TestCommit.java Wed Apr 03 21:28:06 2013 +0200 +++ b/test/org/tmatesoft/hg/test/TestCommit.java Tue Apr 09 17:15:30 2013 +0200 @@ -23,13 +23,11 @@ import java.io.File; import java.io.FileInputStream; -import java.io.FileWriter; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.List; -import org.hamcrest.CoreMatchers; import org.junit.Test; import org.tmatesoft.hg.core.HgAddRemoveCommand; import org.tmatesoft.hg.core.HgCatCommand;