Mercurial > hg > mercurial
changeset 511:f2666e817701
Detect changes in subrepos
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java Mon Nov 12 21:20:00 2012 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java Thu Nov 15 16:40:22 2012 +0400 @@ -1,5 +1,6 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial; +import com.intellij.openapi.util.Trinity; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.*; import jetbrains.buildServer.log.Loggers; import jetbrains.buildServer.util.FileUtil; @@ -10,6 +11,7 @@ import java.io.IOException; import java.util.*; +import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static jetbrains.buildServer.buildTriggers.vcs.mercurial.HgFileUtil.deleteDir; import static jetbrains.buildServer.util.FileUtil.isEmptyDir; @@ -87,6 +89,10 @@ return new VersionCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir); } + public ParentsCommand parents() { + return new ParentsCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir); + } + public String path() { return myWorkingDir.getAbsolutePath(); } @@ -153,11 +159,79 @@ return getSubrepositories(new ChangeSet(revision)); } + public List<SubRepoConfigChange> getSubrepoConfigChanges(@NotNull String revision) throws VcsException { + if (containsSubrepoConfigChange(revision)) { + List<String> parents = parents().ofRevision(revision).call(); + return getSubrepoConfigChanges(revision, parents.get(0));//what about merges? + } + return emptyList(); + } + + public List<SubRepoConfigChange> getSubrepoConfigChanges(@NotNull ChangeSet cset) { + if (containsSubrepoConfigChange(cset)) + return getSubrepoConfigChanges(cset.getId(), cset.getParents().get(0).getId()); + return emptyList(); + } + + private List<SubRepoConfigChange> getSubrepoConfigChanges(@NotNull String revision, @NotNull String parentRevision) { + Map<String, SubRepo> curSubrepos = getSubrepositories(revision); + Map<String, SubRepo> prevSubrepos = getSubrepositories(parentRevision); + return getSubrepoConfigChanges(prevSubrepos, curSubrepos); + + } + + private List<SubRepoConfigChange> getSubrepoConfigChanges(@NotNull Map<String, SubRepo> prevSubrepos, + @NotNull Map<String, SubRepo> curSubrepos) { + List<SubRepoConfigChange> configChanges = new ArrayList<SubRepoConfigChange>(); + for (Map.Entry<String, SubRepo> e : curSubrepos.entrySet()) { + SubRepo curSubrepo = e.getValue(); + SubRepo prevSubrepo = prevSubrepos.remove(e.getKey()); + if (prevSubrepo == null) { + configChanges.add(new SubRepoConfigChange(e.getKey(), null, curSubrepo)); + } else { + String prevRevision = prevSubrepo.revision(); + String currentRevision = curSubrepo.revision(); + if (!currentRevision.equals(prevRevision)) + configChanges.add(new SubRepoConfigChange(e.getKey(), prevSubrepo, curSubrepo)); + } + } + for (Map.Entry<String, SubRepo> e : prevSubrepos.entrySet()) { + configChanges.add(new SubRepoConfigChange(e.getKey(), e.getValue(), null)); + } + return configChanges; + } + + private boolean containsSubrepoConfigChange(@NotNull ChangeSet cset) { + for (FileStatus f : cset.getModifiedFiles()) { + if (containsSubrepoConfigChange(f)) + return true; + } + return false; + } + + private boolean containsSubrepoConfigChange(@NotNull String revision) throws VcsException { + List<FileStatus> changedFiles = status() + .fromRevision(revision) + .toRevision(revision) + .showAllFiles() + .call(); + for (FileStatus f : changedFiles) { + if (containsSubrepoConfigChange(f)) + return true; + } + return false; + } + + private boolean containsSubrepoConfigChange(@NotNull FileStatus f) { + return f.getPath().equals(".hgsubstate"); + } + + //path->subrepo public Map<String, SubRepo> getSubrepositories(@NotNull ChangeSet cset) { String revId = cset.getId(); Map<String, SubRepo> subrepos = mySubreposCache.get(revId); if (subrepos != null) - return subrepos; + return new HashMap<String, SubRepo>(subrepos); CatCommand cc = cat(); cc.setRevId(revId); File catDir = null; @@ -167,7 +241,7 @@ File hgsubstate = new File(catDir, ".hgsubstate"); subrepos = readSubrepositories(hgsub, hgsubstate); mySubreposCache.put(revId, subrepos); - return subrepos; + return new HashMap<String, SubRepo>(subrepos); } catch (VcsException e) { return emptyMap(); } finally { @@ -190,15 +264,11 @@ String path = entry.getKey(); String url = entry.getValue(); String revision = path2revision.get(path); - if (revision != null) { + if (revision != null) result.put(path, new SubRepo(this, path, url, revision)); - } else { -// myLogger.warning("Cannot find revision for subrepository at path " + path + " skip it"); - } } return result; } catch (IOException e) { -// myLogger.warning("Error while trying to read subrepositories " + e.getMessage()); return emptyMap(); } } else { @@ -211,11 +281,8 @@ Map<String, String> result = new HashMap<String, String>(); for (String line : FileUtil.readFile(hgsub)) { String[] parts = line.split(" = "); - if (parts.length == 2) { + if (parts.length == 2) result.put(parts[0], parts[1]); - } else { -// myLogger.warning("Cannot parse the line '" + line + "' from .hgsub, skip it"); - } } return result; } @@ -226,11 +293,8 @@ Map<String, String> result = new HashMap<String, String>(); for (String line : FileUtil.readFile(hgsubstate)) { String[] parts = line.split(" "); - if (parts.length == 2) { + if (parts.length == 2) result.put(parts[1], parts[0]); - } else { -// myLogger.warning("Cannot parse the line '" + line + "' from .hgsubstate, skip it"); - } } return result; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SubRepoConfigChange.java Thu Nov 15 16:40:22 2012 +0400 @@ -0,0 +1,37 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A change in subrepo configuration + */ +public class SubRepoConfigChange { + + private final String myPath; + private final SubRepo myPrevious; + private final SubRepo myCurrent; + + public SubRepoConfigChange(@NotNull String path, + @Nullable SubRepo previous, + @Nullable SubRepo current) { + myPath = path; + myPrevious = previous; + myCurrent = current; + } + + @NotNull + public String getPath() { + return myPath; + } + + @Nullable + public SubRepo getPrevious() { + return myPrevious; + } + + @Nullable + public SubRepo getCurrent() { + return myCurrent; + } +}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java Mon Nov 12 21:20:00 2012 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java Thu Nov 15 16:40:22 2012 +0400 @@ -15,6 +15,7 @@ */ package jetbrains.buildServer.buildTriggers.vcs.mercurial.command; +import jetbrains.buildServer.vcs.VcsException; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -58,6 +59,10 @@ return cl; } + protected CommandResult runCommand(@NotNull MercurialCommandLine cli) throws VcsException { + return CommandUtil.runCommand(cli, myCommandSettings); + } + protected Set<String> getPrivateData() { return emptySet(); }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/HgVcsRoot.java Mon Nov 12 21:20:00 2012 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/HgVcsRoot.java Thu Nov 15 16:40:22 2012 +0400 @@ -43,8 +43,12 @@ private File myCustomWorkingDir; public HgVcsRoot(@NotNull final VcsRoot vcsRoot) { + this(vcsRoot, vcsRoot.getProperty(Constants.REPOSITORY_PROP)); + } + + public HgVcsRoot(@NotNull VcsRoot vcsRoot, @NotNull String repository) { myRoot = vcsRoot; - myRepository = getProperty(Constants.REPOSITORY_PROP); + myRepository = repository; myHgCommandPath = getProperty(Constants.HG_COMMAND_PATH_PROP); myBranchName = getProperty(Constants.BRANCH_NAME_PROP); myCustomClonePath = getProperty(Constants.SERVER_CLONE_PATH_PROP); @@ -61,6 +65,10 @@ return myRepository; } + public HgVcsRoot withUrl(@NotNull String repositoryUrl) { + return new HgVcsRoot(this, repositoryUrl); + } + /** * Returns name of the branch to use (returns 'default' if no branch specified) * @return see above
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ParentsCommand.java Thu Nov 15 16:40:22 2012 +0400 @@ -0,0 +1,38 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial.command; + +import jetbrains.buildServer.vcs.VcsException; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class ParentsCommand extends BaseCommand { + + private String myRevision; + + public ParentsCommand(@NotNull CommandSettings commandSettings, + @NotNull String hgPath, + @NotNull File workingDir) { + super(commandSettings, hgPath, workingDir); + } + + public ParentsCommand ofRevision(@NotNull String revision) { + myRevision = revision; + return this; + } + + public List<String> call() throws VcsException { + MercurialCommandLine cli = createCommandLine(); + cli.addParameter("parents"); + cli.addParameter("-q"); + if (myRevision != null) + cli.addParameters("-r", myRevision); + CommandResult res = runCommand(cli); + List<String> parentRevisions = new ArrayList<String>(); + for (String line : res.getStdout().split("\n")) { + parentRevisions.add(new ChangeSet(line).getId()); + } + return parentRevisions; + } +}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/VcsRootCommand.java Mon Nov 12 21:20:00 2012 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/VcsRootCommand.java Thu Nov 15 16:40:22 2012 +0400 @@ -23,10 +23,6 @@ } - protected CommandResult runCommand(@NotNull MercurialCommandLine cli) throws VcsException { - return CommandUtil.runCommand(cli, myCommandSettings); - } - protected CommandResult runCommand(@NotNull MercurialCommandLine cli, @NotNull CommandSettings s) throws VcsException { s.setPrivateData(getPrivateData()); return CommandUtil.runCommand(cli, s);
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Mon Nov 12 21:20:00 2012 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Thu Nov 15 16:40:22 2012 +0400 @@ -15,6 +15,7 @@ */ package jetbrains.buildServer.buildTriggers.vcs.mercurial; +import com.intellij.openapi.util.Trinity; import jetbrains.buildServer.BuildAgent; import jetbrains.buildServer.Used; import jetbrains.buildServer.buildTriggers.vcs.AbstractVcsPropertiesProcessor; @@ -590,7 +591,8 @@ String fromCommit = new ChangeSetRevision(fromVersion).getId(); String toCommit = new ChangeSetRevision(toVersion).getId(); try { - List<ChangeSet> changesets = createRepo(root).collectChanges(root) + ServerHgRepo repo = createRepo(root); + List<ChangeSet> changesets = repo.collectChanges(root) .fromRevision(fromCommit) .toRevision(toCommit) .call(); @@ -600,6 +602,8 @@ if (cset.getId().equals(fromCommit)) iter.remove();//skip already reported changes } + if (myConfig.detectSubrepoChanges()) + changesets.addAll(getSubrepoChangesets(root, repo, changesets)); return changesets; } catch (UnknownRevisionException e) { Loggers.VCS.warn("Revision '" + e.getRevision() + "' is unknown, will return no changes"); @@ -607,6 +611,26 @@ } } + @NotNull + private List<ChangeSet> getSubrepoChangesets(@NotNull HgVcsRoot root, + @NotNull HgRepo repo, + @NotNull List<ChangeSet> csets) throws VcsException { + List<ChangeSet> subrepoCsets = new ArrayList<ChangeSet>(); + for (ChangeSet cset : csets) { + List<SubRepoConfigChange> subrepoConfigChanges = repo.getSubrepoConfigChanges(cset); + for (SubRepoConfigChange c : subrepoConfigChanges) { + if (c.getCurrent() != null && c.getPrevious() != null && c.getCurrent().url().equals(c.getPrevious().url())) { + String subrepoUrl = c.getCurrent().isRelative() ? root.getRepository() + "/" + c.getCurrent().url() : c.getCurrent().url(); + String fromRevision = c.getPrevious().revision(); + String toRevision = c.getCurrent().revision(); + HgVcsRoot subrepoRoot = root.withUrl(subrepoUrl); + syncRepository(subrepoRoot); + subrepoCsets.addAll(getChangesets(subrepoRoot, fromRevision, toRevision)); + } + } + } + return subrepoCsets; + } @NotNull public BuildPatchPolicy getBuildPatchPolicy() {
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfig.java Mon Nov 12 21:20:00 2012 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfig.java Thu Nov 15 16:40:22 2012 +0400 @@ -21,4 +21,6 @@ @NotNull Set<Long> getRevsetParentRootIds(); + + public boolean detectSubrepoChanges(); }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigImpl.java Mon Nov 12 21:20:00 2012 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigImpl.java Thu Nov 15 16:40:22 2012 +0400 @@ -67,4 +67,8 @@ } return ids; } + + public boolean detectSubrepoChanges() { + return false; + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepoTest.java Thu Nov 15 16:40:22 2012 +0400 @@ -0,0 +1,65 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import com.intellij.openapi.diagnostic.Logger; +import jetbrains.buildServer.TempFiles; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.AuthSettings; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.TestCommandSettingsFactory; +import jetbrains.buildServer.log.Log4jFactory; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.Util.copyRepository; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; + +@Test +public class HgRepoTest { + + static { + Logger.setFactory(new Log4jFactory()); + } + + private TempFiles myTempFiles; + + @BeforeMethod + public void setUp() throws IOException { + myTempFiles = new TempFiles(); + } + + @AfterMethod + public void tearDown() { + myTempFiles.cleanup(); + } + + public void subrepos() throws Exception { + File repository = myTempFiles.createTempDir(); + copyRepository(new File("mercurial-tests/testData/subrepos/r1"), repository); + HgRepo repo = new HgRepo(new TestCommandSettingsFactory(), repository, Util.getHgPath(), new AuthSettings()); + List<SubRepoConfigChange> changes = repo.getSubrepoConfigChanges("09c256b6163e"); + assertEquals(1, changes.size()); + SubRepoConfigChange c = changes.get(0); + assertEquals("r2", c.getPath()); + //noinspection ConstantConditions + assertTrue(c.getPrevious().revision().startsWith("9e4a2fef1a1c")); + //noinspection ConstantConditions + assertTrue(c.getCurrent().revision().startsWith("ebb884b1b691")); + + changes = repo.getSubrepoConfigChanges("4d7b3db8779f"); + assertEquals(1, changes.size()); + c = changes.get(0); + assertEquals("r2", c.getPath()); + //noinspection ConstantConditions + assertTrue(c.getPrevious().revision().startsWith("916933c1dd8e")); + assertNull(c.getCurrent()); + + changes = repo.getSubrepoConfigChanges("d350e7209906"); + assertEquals(1, changes.size()); + } + +}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgPathProviderTest.java Mon Nov 12 21:20:00 2012 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgPathProviderTest.java Thu Nov 15 16:40:22 2012 +0400 @@ -46,7 +46,7 @@ private HgVcsRoot createHgRoot() throws Exception { - return new HgVcsRoot(new VcsRootBuilder().withHgPath(myVcsRootHgPath).build()); + return new HgVcsRoot(new VcsRootBuilder().withUrl("some url").withHgPath(myVcsRootHgPath).build()); } }
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigBuilder.java Mon Nov 12 21:20:00 2012 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigBuilder.java Thu Nov 15 16:40:22 2012 +0400 @@ -15,6 +15,7 @@ private String myHgPath; private File myCachesDir; private boolean myDontUseRevsets = false; + private boolean myDetectSubrepoChanges = false; @NotNull public ServerPluginConfig build() { @@ -47,6 +48,10 @@ public Set<Long> getRevsetParentRootIds() { return new HashSet<Long>(); } + + public boolean detectSubrepoChanges() { + return myDetectSubrepoChanges; + } }; } @@ -70,4 +75,9 @@ myDontUseRevsets = true; return this; } + + public ServerPluginConfigBuilder detectSubrepoChanges(boolean doDetect) { + myDetectSubrepoChanges = doDetect; + return this; + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SubrepoChangesTest.java Thu Nov 15 16:40:22 2012 +0400 @@ -0,0 +1,84 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import com.intellij.openapi.diagnostic.Logger; +import jetbrains.buildServer.TempFiles; +import jetbrains.buildServer.log.Log4jFactory; +import jetbrains.buildServer.vcs.CheckoutRules; +import jetbrains.buildServer.vcs.ModificationData; +import jetbrains.buildServer.vcs.VcsRoot; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialSupportBuilder.mercurialSupport; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.Util.copyRepository; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot; +import static org.testng.AssertJUnit.assertEquals; + +@Test +public class SubrepoChangesTest { + + static { + Logger.setFactory(new Log4jFactory()); + } + + private TempFiles myTempFiles; + private MercurialVcsSupport myVcs; + private File myRemoteRepo1; + private File myRemoteRepo2; + private File myRemoteRepo3; + + @BeforeMethod + public void setUp() throws IOException { + myTempFiles = new TempFiles(); + ServerPluginConfig pluginConfig = new ServerPluginConfigBuilder() + .cachesDir(myTempFiles.createTempDir()) + .detectSubrepoChanges(true) + .build(); + File remoteRepoParentDir = myTempFiles.createTempDir(); + myRemoteRepo1 = new File(remoteRepoParentDir, "r1"); + myRemoteRepo2 = new File(remoteRepoParentDir, "r2"); + myRemoteRepo3 = new File(remoteRepoParentDir, "r3"); + copyRepository(new File("mercurial-tests/testData/subrepos/r1"), myRemoteRepo1); + copyRepository(new File("mercurial-tests/testData/subrepos/r2"), myRemoteRepo2); + copyRepository(new File("mercurial-tests/testData/subrepos/r3"), myRemoteRepo3); + myVcs = mercurialSupport().withConfig(pluginConfig).build(); + } + + @AfterMethod + public void tearDown() { + myTempFiles.cleanup(); + } + + + public void should_report_changes_from_subrepos() throws Exception { + VcsRoot root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).build(); + List<ModificationData> changes = myVcs.collectChanges(root, "d350e7209906", "09c256b6163e", CheckoutRules.DEFAULT); + assertEquals(3, changes.size()); + } + + + public void should_not_report_any_changes_when_subrepo_removed() throws Exception { + VcsRoot root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).build(); + List<ModificationData> changes = myVcs.collectChanges(root, "34017377d9c3", "4d7b3db8779f", CheckoutRules.DEFAULT); + assertEquals(1, changes.size()); + } + + + public void should_not_report_any_changes_when_subrepo_added() throws Exception { + VcsRoot root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).build(); + List<ModificationData> changes = myVcs.collectChanges(root, "4d7b3db8779f", "d350e7209906", CheckoutRules.DEFAULT); + assertEquals(1, changes.size()); + } + + + public void should_report_subrepo_changes_recursevly() throws Exception { + VcsRoot root = vcsRoot().withUrl(myRemoteRepo1.getAbsolutePath()).build(); + List<ModificationData> changes = myVcs.collectChanges(root, "09c256b6163e", "d64d9799c143", CheckoutRules.DEFAULT); + assertEquals(5, changes.size()); + } +}
--- a/mercurial-tests/src/testng.xml Mon Nov 12 21:20:00 2012 +0400 +++ b/mercurial-tests/src/testng.xml Thu Nov 15 16:40:22 2012 +0400 @@ -26,6 +26,8 @@ <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.ListFilesSupportTest"/> <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.RevisionFormatTest"/> <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.HgFileUtilTest"/> + <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.SubrepoChangesTest"/> + <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.HgRepoTest"/> </classes> </test> </suite>
--- a/mercurial-tests/testData/subrepos/README Mon Nov 12 21:20:00 2012 +0400 +++ b/mercurial-tests/testData/subrepos/README Thu Nov 15 16:40:22 2012 +0400 @@ -1,13 +1,21 @@ r1 history: +5:d64d9799c143 Recursive subrepos <- subrepository r2 = ../r3 (514c3e09cddf) +4:09c256b6163e Subrepo update <- subrepository r2 = ../r3 (ebb884b1b691) 3:d350e7209906 Add different subrepository in the same path <- subrepository r2 = ../r3 (9e4a2fef1a1c) 2:4d7b3db8779f Remove subrepository <- subrepository removed 1:34017377d9c3 Add subrepository <- subrepository r2 = ../r2 (916933c1dd8e) 0:e4eced2b7381 Initial commit r2 history: +2:ac0003deae69 three +1:29053b4b29ce two 0:916933c1dd8e Initial commit r3 history: +4:514c3e09cddf Upgrade subrepo <- subrepository r2 = ../r2 (ac0003deae69) +3:1f9eb39a3921 Add subrepo <- subrepository r2 = ../r2 (916933c1dd8e) +2:ebb884b1b691 two +1:f41168ce47b7 one 0:9e4a2fef1a1c Initial commit
--- a/mercurial-tests/testData/subrepos/r1/hg/undo.desc Mon Nov 12 21:20:00 2012 +0400 +++ b/mercurial-tests/testData/subrepos/r1/hg/undo.desc Thu Nov 15 16:40:22 2012 +0400 @@ -1,2 +1,2 @@ -3 +4 commit