Mercurial > jhg
changeset 563:ca56a36c2eea
HgCheckoutCommand: clean parameter, discard changes in WD, test for clean checkout
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 28 Feb 2013 16:34:33 +0100 |
parents | 6fbca6506bb5 |
children | e6407313bab7 |
files | src/org/tmatesoft/hg/core/HgCheckoutCommand.java src/org/tmatesoft/hg/repo/CommitFacility.java test/org/tmatesoft/hg/test/TestCheckout.java |
diffstat | 3 files changed, 66 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/core/HgCheckoutCommand.java Thu Feb 28 15:57:04 2013 +0100 +++ b/src/org/tmatesoft/hg/core/HgCheckoutCommand.java Thu Feb 28 16:34:33 2013 +0100 @@ -31,8 +31,12 @@ import org.tmatesoft.hg.internal.Internals; 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.HgManifest.Flags; import org.tmatesoft.hg.repo.HgRepository; import org.tmatesoft.hg.repo.HgRuntimeException; @@ -54,12 +58,26 @@ private final HgRepository repo; private int revisionToCheckout = HgRepository.BAD_REVISION; + private boolean cleanCheckout; public HgCheckoutCommand(HgRepository hgRepo) { repo = hgRepo; } /** + * Whether to discard all uncommited changes prior to check-out. + * + * NOTE, at the moment, only clean checkout is supported! + * + * @param clean <code>true</code> to discard any change + * @return <code>this</code> for convenience + */ + public HgCheckoutCommand clean(boolean clean) { + cleanCheckout = clean; + return this; + } + + /** * Select revision to check out * * @param nodeid revision @@ -77,12 +95,15 @@ /** * Select revision to check out using local revision index * - * @param changesetIndex local revision index + * @param changesetIndex local revision index, or {@link HgRepository#TIP} * @return <code>this</code> 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); } @@ -99,8 +120,24 @@ public void execute() throws HgException, CancelledException { try { Internals internalRepo = Internals.getInstance(repo); - // FIXME remove tracked files from wd (perhaps, just forget 'Added'?) - // TODO + if (cleanCheckout) { + // remove tracked files from wd (perhaps, just forget 'Added'?) + // for now, just delete each and every tracked file + // TODO WorkingCopy container with getFile(HgDataFile/Path) to access files in WD + HgDirstate dirstate = new HgInternals(repo).getDirstate(); + dirstate.walk(new HgDirstate.Inspector() { + + public boolean next(EntryKind kind, Record entry) { + File f = new File(repo.getWorkingDir(), entry.name().toString()); + if (f.exists()) { + f.delete(); + } + return true; + } + }); + } else { + throw new HgBadArgumentException("Sorry, only clean checkout is supported now, use #clean(true)", null); + } final DirstateBuilder dirstateBuilder = new DirstateBuilder(internalRepo); final CheckoutWorker worker = new CheckoutWorker(internalRepo); HgManifest.Inspector insp = new HgManifest.Inspector() { @@ -127,9 +164,9 @@ worker.checkFailed(); File dirstateFile = internalRepo.getRepositoryFile(Dirstate); try { - FileChannel dirstate = new FileOutputStream(dirstateFile).getChannel(); - dirstateBuilder.serialize(dirstate); - dirstate.close(); + FileChannel dirstateFileChannel = new FileOutputStream(dirstateFile).getChannel(); + dirstateBuilder.serialize(dirstateFileChannel); + dirstateFileChannel.close(); } catch (IOException ex) { throw new HgIOException("Can't write down new directory state", ex, dirstateFile); }
--- a/src/org/tmatesoft/hg/repo/CommitFacility.java Thu Feb 28 15:57:04 2013 +0100 +++ b/src/org/tmatesoft/hg/repo/CommitFacility.java Thu Feb 28 16:34:33 2013 +0100 @@ -36,7 +36,6 @@ import org.tmatesoft.hg.internal.FNCacheFile; import org.tmatesoft.hg.internal.ManifestEntryBuilder; import org.tmatesoft.hg.internal.ManifestRevision; -import org.tmatesoft.hg.internal.RequiresFile; import org.tmatesoft.hg.internal.RevlogStream; import org.tmatesoft.hg.internal.RevlogStreamWriter; import org.tmatesoft.hg.util.Pair;
--- a/test/org/tmatesoft/hg/test/TestCheckout.java Thu Feb 28 15:57:04 2013 +0100 +++ b/test/org/tmatesoft/hg/test/TestCheckout.java Thu Feb 28 16:34:33 2013 +0100 @@ -17,12 +17,13 @@ package org.tmatesoft.hg.test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.tmatesoft.hg.repo.HgRepository.TIP; import static org.tmatesoft.hg.test.RepoUtils.cloneRepoToTempLocation; import java.io.File; import java.io.FileFilter; -import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.tmatesoft.hg.core.HgCheckoutCommand; @@ -48,12 +49,12 @@ @Test public void testCleanCheckoutInEmptyDir() throws Exception { - File testRepoLoc = cloneRepoToTempLocation("log-1", "test-checkoutClean", true); + File testRepoLoc = cloneRepoToTempLocation("log-1", "test-checkout-clean", true); repo = new HgLookup().detect(testRepoLoc); // nothing but .hg dir assertEquals("[sanity]", 0, testRepoLoc.listFiles(new FilesOnlyFilter()).length); - new HgCheckoutCommand(repo).changeset(1).execute(); + new HgCheckoutCommand(repo).clean(true).changeset(1).execute(); errorCollector.assertEquals(2, testRepoLoc.listFiles(new FilesOnlyFilter()).length); Pair<Nodeid, Nodeid> workingCopyParents = repo.getWorkingCopyParents(); @@ -68,7 +69,7 @@ errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("a"))); errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("b"))); - new HgCheckoutCommand(repo).changeset(3).execute(); + new HgCheckoutCommand(repo).clean(true).changeset(3).execute(); statusOutputParser.reset(); eh.run("hg", "status", "-A"); errorCollector.assertEquals(3, statusOutputParser.getClean().size()); @@ -77,9 +78,24 @@ errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("dir/b"))); } + /** + * Make sure WC is cleared prior to clean checkout + */ @Test - public void testCleanCheckoutInDirtyDir() { - Assert.fail("Make sure WC is cleared prior to clean checkout"); + public void testCleanCheckoutInDirtyDir() throws Exception { + File repoLoc = cloneRepoToTempLocation("log-1", "test-checkout-dirty", false); + File untrackedFile = new File(repoLoc, "aaa"); + RepoUtils.createFile(untrackedFile, "shall survive hg co --clean"); + File modifiedFile = new File(repoLoc, "b"); + assertTrue("[sanity]", modifiedFile.canRead()); + final long modifiedFileInitialLen = modifiedFile.length(); + RepoUtils.modifyFileAppend(modifiedFile, "the change shall not survive"); + assertTrue("[sanity]", modifiedFile.length() > modifiedFileInitialLen); + // + repo = new HgLookup().detect(repoLoc); + new HgCheckoutCommand(repo).clean(true).changeset(TIP).execute(); + errorCollector.assertTrue(untrackedFile.canRead()); + errorCollector.assertEquals(modifiedFileInitialLen, modifiedFile.length()); } @Test @@ -87,7 +103,7 @@ File testRepoLoc = cloneRepoToTempLocation("log-branches", "test-checkoutBranch", true); repo = new HgLookup().detect(testRepoLoc); - new HgCheckoutCommand(repo).changeset(3 /*branch test*/).execute(); + new HgCheckoutCommand(repo).clean(true).changeset(3 /*branch test*/).execute(); StatusOutputParser statusOutputParser = new StatusOutputParser(); eh = new ExecHelper(statusOutputParser, testRepoLoc);