# HG changeset patch # User Artem Tikhomirov # Date 1358275579 -3600 # Node ID 47b7bedf0569d849920703e67deabbda68e70daf # Parent 2f9ed6bcefa2e737c5f65832f5b299b4a1e5550f Tests for present HgCheckoutCommand functionality. Update branch information on checkout. Use UTF8 encoding for the branch file diff -r 2f9ed6bcefa2 -r 47b7bedf0569 src/org/tmatesoft/hg/core/HgCheckoutCommand.java --- a/src/org/tmatesoft/hg/core/HgCheckoutCommand.java Tue Jan 15 17:07:19 2013 +0100 +++ b/src/org/tmatesoft/hg/core/HgCheckoutCommand.java Tue Jan 15 19:46:19 2013 +0100 @@ -16,14 +16,17 @@ */ package org.tmatesoft.hg.core; +import static org.tmatesoft.hg.repo.HgRepositoryFiles.Branch; import static org.tmatesoft.hg.repo.HgRepositoryFiles.Dirstate; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStreamWriter; import java.nio.channels.FileChannel; import org.tmatesoft.hg.internal.DirstateBuilder; +import org.tmatesoft.hg.internal.EncodingHelper; import org.tmatesoft.hg.internal.Experimental; import org.tmatesoft.hg.internal.Internals; import org.tmatesoft.hg.internal.WorkingDirFileWriter; @@ -130,7 +133,19 @@ } catch (IOException ex) { throw new HgIOException("Can't write down new directory state", ex, dirstateFile); } - // FIXME write down branch file + String branchName = repo.getChangelog().range(revisionToCheckout, revisionToCheckout).get(0).branch(); + assert branchName != null; + if (!HgRepository.DEFAULT_BRANCH_NAME.equals(branchName)) { + File branchFile = internalRepo.getRepositoryFile(Branch); + try { + // branch file is UTF-8, see http://mercurial.selenic.com/wiki/EncodingStrategy#UTF-8_strings + OutputStreamWriter ow = new OutputStreamWriter(new FileOutputStream(branchFile), EncodingHelper.getUTF8()); + ow.write(branchName); + ow.close(); + } catch (IOException ex) { + throw new HgIOException("Can't write down branch information", ex, branchFile); + } + } } catch (HgRuntimeException ex) { throw new HgLibraryFailureException(ex); } diff -r 2f9ed6bcefa2 -r 47b7bedf0569 src/org/tmatesoft/hg/internal/DirstateReader.java --- a/src/org/tmatesoft/hg/internal/DirstateReader.java Tue Jan 15 17:07:19 2013 +0100 +++ b/src/org/tmatesoft/hg/internal/DirstateReader.java Tue Jan 15 19:46:19 2013 +0100 @@ -17,14 +17,16 @@ package org.tmatesoft.hg.internal; import static org.tmatesoft.hg.core.Nodeid.NULL; +import static org.tmatesoft.hg.repo.HgRepositoryFiles.Branch; import static org.tmatesoft.hg.repo.HgRepositoryFiles.Dirstate; import static org.tmatesoft.hg.util.LogFacility.Severity.Debug; import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; +import java.io.InputStreamReader; import org.tmatesoft.hg.core.Nodeid; import org.tmatesoft.hg.repo.HgDirstate; @@ -158,11 +160,17 @@ * @return branch associated with the working directory */ public static String readBranch(Internals internalRepo) throws HgInvalidControlFileException { - File branchFile = internalRepo.getFileFromRepoDir("branch"); // FIXME constant in the HgRepositoryFiles + File branchFile = internalRepo.getRepositoryFile(Branch); String branch = HgRepository.DEFAULT_BRANCH_NAME; if (branchFile.exists()) { try { - BufferedReader r = new BufferedReader(new FileReader(branchFile)); + // branch file is UTF-8 encoded, see http://mercurial.selenic.com/wiki/EncodingStrategy#UTF-8_strings + // shall not use system-default encoding (FileReader) when reading it! + // Perhaps, shall use EncodingHelper.fromBranch and InputStream instead, for uniformity? + // Since whole file is in UTF8, InputStreamReader is a convenience over InputStream, + // which we use elsewhere (together with EncodingHelper) - other files are usually a mix of binary data + // and encoded text (hence, InputStreamReader with charset is not an option there) + BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(branchFile), EncodingHelper.getUTF8())); String b = r.readLine(); if (b != null) { b = b.trim().intern(); diff -r 2f9ed6bcefa2 -r 47b7bedf0569 src/org/tmatesoft/hg/internal/EncodingHelper.java --- a/src/org/tmatesoft/hg/internal/EncodingHelper.java Tue Jan 15 17:07:19 2013 +0100 +++ b/src/org/tmatesoft/hg/internal/EncodingHelper.java Tue Jan 15 19:46:19 2013 +0100 @@ -111,4 +111,7 @@ return encoder.charset(); } + public static Charset getUTF8() { + return Charset.forName("UTF-8"); + } } diff -r 2f9ed6bcefa2 -r 47b7bedf0569 src/org/tmatesoft/hg/repo/HgRepositoryFiles.java --- a/src/org/tmatesoft/hg/repo/HgRepositoryFiles.java Tue Jan 15 17:07:19 2013 +0100 +++ b/src/org/tmatesoft/hg/repo/HgRepositoryFiles.java Tue Jan 15 19:46:19 2013 +0100 @@ -29,7 +29,8 @@ Dirstate(false, "dirstate"), HgLocalTags(false, "localtags"), HgSub(".hgsub"), HgSubstate(".hgsubstate"), LastMessage(false, "last-message.txt"), - Bookmarks(false, "bookmarks"), BookmarksCurrent(false, "bookmarks.current"); + Bookmarks(false, "bookmarks"), BookmarksCurrent(false, "bookmarks.current"), + Branch(false, "branch"); private final String fname; private final boolean livesInWC; diff -r 2f9ed6bcefa2 -r 47b7bedf0569 test/org/tmatesoft/hg/test/TestCheckout.java --- a/test/org/tmatesoft/hg/test/TestCheckout.java Tue Jan 15 17:07:19 2013 +0100 +++ b/test/org/tmatesoft/hg/test/TestCheckout.java Tue Jan 15 19:46:19 2013 +0100 @@ -16,8 +16,20 @@ */ package org.tmatesoft.hg.test; +import static org.junit.Assert.assertEquals; + +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; +import org.tmatesoft.hg.core.Nodeid; +import org.tmatesoft.hg.repo.HgLookup; +import org.tmatesoft.hg.repo.HgRepository; +import org.tmatesoft.hg.util.Pair; +import org.tmatesoft.hg.util.Path; /** * @@ -26,10 +38,42 @@ */ public class TestCheckout { + @Rule + public ErrorCollectorExt errorCollector = new ErrorCollectorExt(); + + private HgRepository repo; + private ExecHelper eh; + @Test - public void testCleanCheckoutInEmptyDir() { - Assert.fail("clone without update, checkout, status"); + public void testCleanCheckoutInEmptyDir() throws Exception { + File testRepoLoc = TestRevert.cloneRepoToTempLocation(Configuration.get().find("log-1"), "test-checkoutClean", true); + repo = new HgLookup().detect(testRepoLoc); + // nothing but .hg dir + assertEquals("[sanity]", 0, testRepoLoc.listFiles(new FilesOnlyFilter()).length); + + new HgCheckoutCommand(repo).changeset(1).execute(); + errorCollector.assertEquals(2, testRepoLoc.listFiles(new FilesOnlyFilter()).length); + + Pair workingCopyParents = repo.getWorkingCopyParents(); + errorCollector.assertEquals("da3461cd828dae8eb5fd11189d40e9df1961f191", workingCopyParents.first().toString()); + errorCollector.assertEquals(Nodeid.NULL, workingCopyParents.second()); + errorCollector.assertEquals(HgRepository.DEFAULT_BRANCH_NAME, repo.getWorkingCopyBranchName()); + + StatusOutputParser statusOutputParser = new StatusOutputParser(); + eh = new ExecHelper(statusOutputParser, testRepoLoc); + eh.run("hg", "status", "-A"); + errorCollector.assertEquals(2, statusOutputParser.getClean().size()); + errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("a"))); + errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("b"))); + + new HgCheckoutCommand(repo).changeset(3).execute(); + statusOutputParser.reset(); + eh.run("hg", "status", "-A"); + errorCollector.assertEquals(3, statusOutputParser.getClean().size()); + errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("b"))); + errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("d"))); + errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("dir/b"))); } @Test @@ -38,7 +82,26 @@ } @Test - public void testBranchCheckout() { - Assert.fail("Make sure branch file is written"); + public void testBranchCheckout() throws Exception { + File testRepoLoc = TestRevert.cloneRepoToTempLocation(Configuration.get().find("log-branches"), "test-checkoutBranch", true); + repo = new HgLookup().detect(testRepoLoc); + + new HgCheckoutCommand(repo).changeset(3 /*branch test*/).execute(); + + StatusOutputParser statusOutputParser = new StatusOutputParser(); + eh = new ExecHelper(statusOutputParser, testRepoLoc); + eh.run("hg", "status", "-A"); + errorCollector.assertEquals(3, statusOutputParser.getClean().size()); + errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("a"))); + errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("b"))); + errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("c"))); + + errorCollector.assertEquals("test", repo.getWorkingCopyBranchName()); + } + + private static final class FilesOnlyFilter implements FileFilter { + public boolean accept(File f) { + return f.isFile(); + } } } diff -r 2f9ed6bcefa2 -r 47b7bedf0569 test/org/tmatesoft/hg/test/TestRevert.java --- a/test/org/tmatesoft/hg/test/TestRevert.java Tue Jan 15 17:07:19 2013 +0100 +++ b/test/org/tmatesoft/hg/test/TestRevert.java Tue Jan 15 19:46:19 2013 +0100 @@ -21,6 +21,8 @@ import java.io.File; import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; import org.junit.Rule; import org.junit.Test; @@ -39,6 +41,7 @@ @Rule public ErrorCollectorExt errorCollector = new ErrorCollectorExt(); + private HgRepository repo; private ExecHelper eh; @@ -48,13 +51,8 @@ @Test public void testCommand() throws Exception { - File tmpDir = Configuration.get().getTempDir(); - tmpDir.mkdirs(); - eh = new ExecHelper(new OutputParser.Stub(), tmpDir); - File testRepoLoc = TestIncoming.createEmptyDir("test-revert"); // get a copy of a repository - eh.run("hg", "clone", Configuration.get().find("log-1").getWorkingDir().toString(), testRepoLoc.getName()); - assertEquals("[sanity]", 0, eh.getExitValue()); + File testRepoLoc = cloneRepoToTempLocation(Configuration.get().find("log-1"), "test-revert", false); repo = new HgLookup().detect(testRepoLoc); Path targetFile = Path.create("b"); @@ -72,10 +70,10 @@ statusParser.reset(); eh.run("hg", "status", "-A"); - assertEquals(3, statusParser.getClean().size()); - assertTrue(statusParser.getClean().contains(targetFile)); - assertEquals(1, statusParser.getUnknown().size()); - assertEquals(targetFile.toString() + ".orig", statusParser.getUnknown().get(0).toString()); + errorCollector.assertEquals(3, statusParser.getClean().size()); + errorCollector.assertTrue(statusParser.getClean().contains(targetFile)); + errorCollector.assertEquals(1, statusParser.getUnknown().size()); + errorCollector.assertEquals(targetFile.toString() + ".orig", statusParser.getUnknown().get(0).toString()); } private static void modifyFileAppend(File f) throws Exception { @@ -84,4 +82,19 @@ fos.write("XXX".getBytes()); fos.close(); } + + static File cloneRepoToTempLocation(HgRepository repo, String name, boolean noupdate) throws IOException, InterruptedException { + File testRepoLoc = TestIncoming.createEmptyDir(name); + ExecHelper eh = new ExecHelper(new OutputParser.Stub(), testRepoLoc.getParentFile()); + ArrayList cmd = new ArrayList(); + cmd.add("hg"); cmd.add("clone"); + if (noupdate) { + cmd.add("--noupdate"); + } + cmd.add(repo.getWorkingDir().toString()); + cmd.add(testRepoLoc.getName()); + eh.run(cmd.toArray(new String[cmd.size()])); + assertEquals("[sanity]", 0, eh.getExitValue()); + return testRepoLoc; + } }