Mercurial > hg > mercurial
changeset 666:557d41234a97
Merge branch Gaya-8.0.x
author | Dmitry Neverov <dmitry.neverov@jetbrains.com> |
---|---|
date | Tue, 01 Oct 2013 12:52:11 +0400 |
parents | cdbda2058141 (diff) 55cf557a14de (current diff) |
children | bcee3a8b2c7b |
files | |
diffstat | 149 files changed, 1636 insertions(+), 386 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.idea/codeStyleSettings.xml Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectCodeStyleSettingsManager"> + <option name="PER_PROJECT_SETTINGS"> + <value> + <option name="USE_SAME_INDENTS" value="true" /> + <option name="IGNORE_SAME_INDENTS_FOR_LANGUAGES" value="true" /> + <option name="OTHER_INDENT_OPTIONS"> + <value> + <option name="INDENT_SIZE" value="2" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="2" /> + <option name="USE_TAB_CHARACTER" value="false" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </value> + </option> + <option name="LINE_SEPARATOR" value=" " /> + <option name="FIELD_NAME_PREFIX" value="my" /> + <option name="STATIC_FIELD_NAME_PREFIX" value="our" /> + <option name="RIGHT_MARGIN" value="140" /> + <XML> + <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" /> + </XML> + <codeStyleSettings language="CSS"> + <indentOptions> + <option name="INDENT_SIZE" value="2" /> + <option name="TAB_SIZE" value="2" /> + </indentOptions> + </codeStyleSettings> + <codeStyleSettings language="CoffeeScript"> + <indentOptions> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + </indentOptions> + </codeStyleSettings> + <codeStyleSettings language="Groovy"> + <indentOptions> + <option name="INDENT_SIZE" value="2" /> + <option name="TAB_SIZE" value="2" /> + </indentOptions> + </codeStyleSettings> + <codeStyleSettings language="JAVA"> + <indentOptions> + <option name="INDENT_SIZE" value="2" /> + <option name="TAB_SIZE" value="2" /> + </indentOptions> + </codeStyleSettings> + <codeStyleSettings language="JSP"> + <indentOptions> + <option name="INDENT_SIZE" value="2" /> + <option name="TAB_SIZE" value="2" /> + </indentOptions> + </codeStyleSettings> + <codeStyleSettings language="JavaScript"> + <indentOptions> + <option name="INDENT_SIZE" value="2" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="2" /> + </indentOptions> + </codeStyleSettings> + <codeStyleSettings language="XML"> + <indentOptions> + <option name="INDENT_SIZE" value="2" /> + <option name="TAB_SIZE" value="2" /> + </indentOptions> + </codeStyleSettings> + <codeStyleSettings language="jet"> + <indentOptions> + <option name="INDENT_SIZE" value="2" /> + <option name="TAB_SIZE" value="2" /> + </indentOptions> + </codeStyleSettings> + <codeStyleSettings language="yaml"> + <indentOptions> + <option name="TAB_SIZE" value="2" /> + </indentOptions> + </codeStyleSettings> + </value> + </option> + <option name="USE_PER_PROJECT_SETTINGS" value="true" /> + </component> +</project> +
--- a/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentRepoFactory.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentRepoFactory.java Tue Oct 01 12:52:11 2013 +0400 @@ -2,16 +2,25 @@ import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.AuthSettings; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CommandSettingsFactory; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; +import jetbrains.buildServer.vcs.VcsException; import org.jetbrains.annotations.NotNull; import java.io.File; -public class AgentRepoFactory { +public class AgentRepoFactory implements HgRepoFactory { private final CommandSettingsFactory myCommandSettingsFactory; + private final HgPathProvider myHgPathProvider; - public AgentRepoFactory(@NotNull CommandSettingsFactory commandSettingsFactory) { + public AgentRepoFactory(@NotNull CommandSettingsFactory commandSettingsFactory, + @NotNull HgPathProvider hgPathProvider) { myCommandSettingsFactory = commandSettingsFactory; + myHgPathProvider = hgPathProvider; + } + + public HgRepo createRepo(@NotNull HgVcsRoot root, @NotNull File workingDir) throws VcsException { + return new HgRepo(myCommandSettingsFactory, workingDir, myHgPathProvider.getHgPath(root), root.getAuthSettings()); } public HgRepo create(@NotNull File workingDir,
--- a/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialAgentSideVcsSupport.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialAgentSideVcsSupport.java Tue Oct 01 12:52:11 2013 +0400 @@ -30,22 +30,19 @@ public class MercurialAgentSideVcsSupport extends AgentVcsSupport implements UpdateByIncludeRules2 { private final AgentPluginConfig myConfig; - private final HgPathProvider myHgPathProvider; private final MirrorManager myMirrorManager; private final AgentRepoFactory myRepoFactory; public MercurialAgentSideVcsSupport(@NotNull AgentPluginConfig pluginConfig, - @NotNull HgPathProvider hgPathProvider, @NotNull MirrorManager mirrorManager, @NotNull AgentRepoFactory repoFactory) { myConfig = pluginConfig; - myHgPathProvider = hgPathProvider; myMirrorManager = mirrorManager; myRepoFactory = repoFactory; } public IncludeRuleUpdater getUpdater(@NotNull final VcsRoot vcsRoot, @NotNull final CheckoutRules checkoutRules, @NotNull final String toVersion, @NotNull final File checkoutDirectory, @NotNull final AgentRunningBuild build, boolean cleanCheckoutRequested) throws VcsException { - return new MercurialIncludeRuleUpdater(myConfig, myMirrorManager, myHgPathProvider, myRepoFactory, vcsRoot, toVersion, build); + return new MercurialIncludeRuleUpdater(myConfig, myMirrorManager, myRepoFactory, vcsRoot, toVersion, build); } @NotNull
--- a/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialIncludeRuleUpdater.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-agent/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialIncludeRuleUpdater.java Tue Oct 01 12:52:11 2013 +0400 @@ -13,7 +13,6 @@ import java.io.File; import java.io.IOException; -import java.net.URI; import java.net.URISyntaxException; import java.util.Map; @@ -24,12 +23,10 @@ */ public class MercurialIncludeRuleUpdater implements IncludeRuleUpdater { - private final AgentPluginConfig myConfig; private final MirrorManager myMirrorManager; private final AgentRepoFactory myRepoFactory; private final HgVcsRoot myRoot; private final AuthSettings myAuthSettings; - private final String myHgPath; private final String myToVersion; private final BuildProgressLogger myLogger; private final boolean myUseLocalMirrors; @@ -38,22 +35,19 @@ public MercurialIncludeRuleUpdater(@NotNull AgentPluginConfig pluginConfig, @NotNull MirrorManager mirrorManager, - @NotNull HgPathProvider hgPathProvider, @NotNull AgentRepoFactory repoFactory, @NotNull VcsRoot root, @NotNull String toVersion, @NotNull AgentRunningBuild build) { - myConfig = pluginConfig; myMirrorManager = mirrorManager; myRepoFactory = repoFactory; myRoot = new HgVcsRoot(root); myAuthSettings = myRoot.getAuthSettings(); - myHgPath = hgPathProvider.getHgPath(myRoot); myToVersion = toVersion; myLogger = build.getBuildLogger(); - myUseLocalMirrors = myConfig.isUseLocalMirrors(build); - myPullTimeout = myConfig.getPullTimeout(build); - myUseTraceback = myConfig.runWithTraceback(build); + myUseLocalMirrors = pluginConfig.isUseLocalMirrors(build); + myPullTimeout = pluginConfig.getPullTimeout(build); + myUseTraceback = pluginConfig.runWithTraceback(build); } @@ -76,7 +70,7 @@ private void updateLocalMirror(@NotNull String repositoryUrl, @NotNull String revision) throws VcsException, IOException { File mirrorDir = myMirrorManager.getMirrorDir(repositoryUrl); - HgRepo mirrorRepo = myRepoFactory.create(mirrorDir, myHgPath, myAuthSettings); + HgRepo mirrorRepo = myRepoFactory.createRepo(myRoot, mirrorDir); if (!mirrorRepo.isValidRepository()) { delete(mirrorDir); myLogger.message("Clone repository " + myAuthSettings.getRepositoryUrlWithHiddenPassword(repositoryUrl) + " into local mirror " + mirrorRepo.path()); @@ -105,7 +99,7 @@ private void updateRepository(@NotNull File workingDir) throws VcsException, IOException { String repositoryUrl = getDefaultPullUrl(myRoot, myUseLocalMirrors); - HgRepo repo = myRepoFactory.create(workingDir, myHgPath, myAuthSettings); + HgRepo repo = myRepoFactory.createRepo(myRoot, workingDir); myLogger.message("Update repository " + workingDir.getAbsolutePath()); if (repo.isEmpty()) {//can do clone only in empty dir myLogger.message("Start cloning from " + (myUseLocalMirrors ? "local mirror " : "") + myAuthSettings.getRepositoryUrlWithHiddenPassword(repositoryUrl)); @@ -140,7 +134,7 @@ private void updateWorkingDir(@NotNull File workingDir, @NotNull String toVersion, @NotNull String repositoryUrl) throws VcsException, IOException { - HgRepo repo = myRepoFactory.create(workingDir, myHgPath, myAuthSettings); + HgRepo repo = myRepoFactory.createRepo(myRoot, workingDir); updateSubrepositories(repo, toVersion, repositoryUrl); doUpdateWorkingDir(repo, toVersion); } @@ -161,7 +155,7 @@ myLogger.message("The url of subrepoConfig was changed between revisions " + workingDirRevision + " and " + toVersion + " , delete the subrepoConfig"); delete(subrepoConfigDir(repo, subrepoConfig)); } - HgRepo subrepository = myRepoFactory.create(subrepoConfigDir(repo, subrepoConfig), myHgPath, myAuthSettings); + HgRepo subrepository = myRepoFactory.createRepo(myRoot, subrepoConfigDir(repo, subrepoConfig)); String subrepoUrl; try { subrepoUrl = subrepoConfig.resolveUrl(parentRepositoryUrl);
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/Constants.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/Constants.java Tue Oct 01 12:52:11 2013 +0400 @@ -29,6 +29,7 @@ String UNCOMPRESSED_TRANSFER = "uncompressedTransfer"; String USER_FOR_TAG = "tagUsername"; String DETECT_SUBREPO_CHANGES = "detectSubrepoChanges"; + String USE_TAGS_AS_BRANCHES = "useTagsAsBranches"; String GLOBAL_DETECT_SUBREPO_CHANGES = "teamcity.hg.detectSubrepoChanges"; }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java Tue Oct 01 12:52:11 2013 +0400 @@ -73,6 +73,20 @@ return new BookmarksCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir, myAuthSettings); } + public TagsCommand tags() { + return new TagsCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir, myAuthSettings); + } + + public Map<String, String> getBranchRevisions(boolean includeBookmarks, boolean includeTags) throws VcsException { + Map<String, String> revisions = new HashMap<String, String>(); + if (includeTags) + revisions.putAll(tags().call()); + if (includeBookmarks && version().call().isEqualsOrGreaterThan(BookmarksCommand.REQUIRED_HG_VERSION)) + revisions.putAll(bookmarks().call()); + revisions.putAll(branches().call()); + return revisions; + } + public StatusCommand status() { return new StatusCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir, myAuthSettings); } @@ -97,6 +111,18 @@ return new ParentsCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir); } + public MergeCommand merge() { + return new MergeCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir); + } + + public ResolveCommand resolve() { + return new ResolveCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir); + } + + public CommitCommand commit() { + return new CommitCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir); + } + public String path() { return myWorkingDir.getAbsolutePath(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepoFactory.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,13 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; +import jetbrains.buildServer.vcs.VcsException; +import org.jetbrains.annotations.NotNull; + +import java.io.File; + +public interface HgRepoFactory { + + HgRepo createRepo(@NotNull HgVcsRoot root, @NotNull File workingDir) throws VcsException; + +}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangeSet.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ChangeSet.java Tue Oct 01 12:52:11 2013 +0400 @@ -16,11 +16,14 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial.command; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Date; import java.util.List; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot.DEFAULT_BRANCH_NAME; + /** * Represents Mercurial change set */ @@ -28,6 +31,7 @@ @NotNull private String myUser; @NotNull private Date myTimestamp; private String myDescription; + private String myBranch = DEFAULT_BRANCH_NAME; private List<ChangeSetRevision> myParents = new ArrayList<ChangeSetRevision>(); private List<FileStatus> myModifiedFiles = new ArrayList<FileStatus>(); @@ -110,4 +114,14 @@ public List<FileStatus> getModifiedFiles() { return myModifiedFiles; } + + @NotNull + public String getBranch() { + return myBranch; + } + + public void setBranch(@Nullable String branch) { + if (branch == null || branch.trim().isEmpty() || DEFAULT_BRANCH_NAME.equals(branch)) branch = DEFAULT_BRANCH_NAME; + myBranch = branch; + } }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResult.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResult.java Tue Oct 01 12:52:11 2013 +0400 @@ -54,6 +54,10 @@ mySettings = settings; } + public int getExitCode() { + return myDelegate.getExitCode(); + } + @NotNull public String getStdout() { return removePrivateData(myDelegate.getStdout(), myPrivateData); @@ -178,6 +182,7 @@ checkFileNotUnderTheRoot(stderr); checkConnectionRefused(stderr); checkAbandonedTransaction(stderr); + checkMergeWithWorkDirAncestor(stderr); } private void checkUnrelatedRepository(@NotNull final String stderr) throws UnrelatedRepositoryException { @@ -219,6 +224,11 @@ throw new AbandonedTransactionFound(); } + private void checkMergeWithWorkDirAncestor(@NotNull final String stderr) throws MergeWithWorkingDirAncestor { + if (stderr.equals("abort: merging with a working directory ancestor has no effect")) + throw new MergeWithWorkingDirAncestor(); + } + private static Set<Integer> setOf(Integer... ints) { return new HashSet<Integer>(asList(ints)); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommitCommand.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,31 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial.command; + +import jetbrains.buildServer.vcs.VcsException; +import org.jetbrains.annotations.NotNull; + +import java.io.File; + +public class CommitCommand extends BaseCommand { + + private String myCommitMessage; + + public CommitCommand(@NotNull CommandSettings commandSettings, + @NotNull String hgPath, + @NotNull File workingDir) { + super(commandSettings, hgPath, workingDir); + } + + public CommitCommand message(@NotNull String commitMessage) { + myCommitMessage = commitMessage; + return this; + } + + public void call() throws VcsException { + MercurialCommandLine cmd = createCommandLine(); + cmd.addParameter("commit"); + cmd.addParameter("-S"); + if (myCommitMessage != null) + cmd.addParameters("-m", myCommitMessage); + runCommand(cmd); + } +}
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/HgVcsRoot.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/HgVcsRoot.java Tue Oct 01 12:52:11 2013 +0400 @@ -15,24 +15,24 @@ */ package jetbrains.buildServer.buildTriggers.vcs.mercurial.command; -import java.io.File; -import java.util.Map; import jetbrains.buildServer.buildTriggers.vcs.mercurial.Constants; import jetbrains.buildServer.buildTriggers.vcs.mercurial.PathUtil; import jetbrains.buildServer.util.StringUtil; import jetbrains.buildServer.vcs.VcsRoot; -import jetbrains.buildServer.vcs.impl.VcsRootImpl; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.File; +import java.util.HashMap; +import java.util.Map; + /** * Represents mercurial VCS root */ -public class HgVcsRoot implements VcsRoot { +public class HgVcsRoot { + public static final String DEFAULT_BRANCH_NAME = "default"; - private static final String DEFAULT_BRANCH_NAME = "default"; - - private final VcsRoot myRoot; + private final Map<String, String> myVcsRootProperties; private final String myRepository; private final String myHgCommandPath; private final String myBranchName; @@ -42,14 +42,15 @@ private final AuthSettings myAuthSettings; private File myCustomWorkingDir; private final boolean myDetectSubrepoChanges; + private final boolean myUseTagsAsBranches; public HgVcsRoot(@NotNull final VcsRoot vcsRoot) { - this(vcsRoot, vcsRoot.getProperty(Constants.REPOSITORY_PROP)); + this(vcsRoot.getProperties()); } - public HgVcsRoot(@NotNull VcsRoot vcsRoot, @NotNull String repository) { - myRoot = vcsRoot; - myRepository = repository; + public HgVcsRoot(@NotNull Map<String, String> vcsRootProperties) { + myVcsRootProperties = vcsRootProperties; + myRepository = getProperty(Constants.REPOSITORY_PROP); myHgCommandPath = getProperty(Constants.HG_COMMAND_PATH_PROP); myBranchName = getProperty(Constants.BRANCH_NAME_PROP); myCustomClonePath = getProperty(Constants.SERVER_CLONE_PATH_PROP); @@ -57,6 +58,13 @@ myUserForTag = getProperty(Constants.USER_FOR_TAG); myAuthSettings = new AuthSettings(getProperty(Constants.USERNAME), getProperty(Constants.PASSWORD)); myDetectSubrepoChanges = Boolean.parseBoolean(getProperty(Constants.DETECT_SUBREPO_CHANGES)); + myUseTagsAsBranches = Boolean.parseBoolean(getProperty(Constants.USE_TAGS_AS_BRANCHES)); + } + + public HgVcsRoot withUrl(@NotNull String repositoryUrl) { + Map<String, String> customUrlProperties = new HashMap<String, String>(getProperties()); + customUrlProperties.put(Constants.REPOSITORY_PROP, repositoryUrl); + return new HgVcsRoot(customUrlProperties); } public String getCustomClonePath() { @@ -67,10 +75,6 @@ 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 @@ -126,6 +130,10 @@ return myDetectSubrepoChanges; } + public boolean useTagsAsBranches() { + return myUseTagsAsBranches; + } + public boolean isSubrepo() { return Boolean.valueOf(getProperty("teamcity.internal.subrepo")); } @@ -145,50 +153,12 @@ return mySubrepoPath + subrepoPath; } - public String getVcsName() { - return myRoot.getVcsName(); - } - - public String getProperty(String propertyName) { - if (Constants.REPOSITORY_PROP.equals(propertyName) && myRepository != null) - return myRepository; - return myRoot.getProperty(propertyName); - } - - public String getProperty(String propertyName, String defaultValue) { - return myRoot.getProperty(propertyName, defaultValue); - } - - public Map<String, String> getProperties() { - return myRoot.getProperties(); - } - - public String convertToString() { - return myRoot.convertToString(); - } - - public String convertToPresentableString() { - return myRoot.convertToPresentableString(); - } - - public long getPropertiesHash() { - return myRoot.getPropertiesHash(); - } - - public String getName() { - return myRoot.getName(); - } - - public long getId() { - return myRoot.getId(); - } - - public Map<String, String> getPublicProperties() { - return myRoot.getPublicProperties(); + public String getProperty(@NotNull String propertyName) { + return myVcsRootProperties.get(propertyName); } @NotNull - public String describe(final boolean verbose) { - return myRoot.describe(verbose); + public Map<String, String> getProperties() { + return myVcsRootProperties; } }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/LogCommand.java Tue Oct 01 12:52:11 2013 +0400 @@ -36,7 +36,8 @@ public class LogCommand extends VcsRootCommand { private final static Logger LOG = Logger.getInstance(LogCommand.class.getName()); - private final static String ZERO_PARENT_ID = "0000000000000000000000000000000000000000"; + public final static String ZERO_PARENT_ID = "0000000000000000000000000000000000000000"; + public final static String ZERO_PARENT_SHORT_ID = "000000000000"; private final static SAXParserFactory ourSAXFactory = SAXParserFactory.newInstance(); private String myFromId;
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/MercurialXmlLogParser.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/MercurialXmlLogParser.java Tue Oct 01 12:52:11 2013 +0400 @@ -34,6 +34,7 @@ public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { if ("logentry".equals(qName)) { myCset = new ChangeSet(getRevision(attrs), getId(attrs)); + myCset.setBranch(attrs.getValue("branch")); } else if ("parent".equals(qName)) { ChangeSetRevision parentCset = new ChangeSetRevision(getRevision(attrs), getId(attrs)); myCset.addParent(parentCset);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/MergeCommand.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,33 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial.command; + +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.MergeConflictException; +import jetbrains.buildServer.vcs.VcsException; +import org.jetbrains.annotations.NotNull; + +import java.io.File; + +public class MergeCommand extends BaseCommand { + + private String myRevision; + + public MergeCommand(@NotNull CommandSettings commandSettings, + @NotNull String hgPath, + @NotNull File workingDir) { + super(commandSettings, hgPath, workingDir); + } + + public MergeCommand revision(@NotNull String revision) { + myRevision = revision; + return this; + } + + public void call() throws VcsException { + MercurialCommandLine cmd = createCommandLine(); + cmd.addParameter("merge"); + if (myRevision != null) + cmd.addParameters("-r", myRevision); + CommandResult result = runCommand(cmd); + if (result.getExitCode() == 1) + throw new MergeConflictException(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/ResolveCommand.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,33 @@ +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; + +import static java.util.Collections.emptyList; + +public class ResolveCommand extends BaseCommand { + + public ResolveCommand(@NotNull CommandSettings commandSettings, + @NotNull String hgPath, + @NotNull File workingDir) { + super(commandSettings, hgPath, workingDir); + } + + public List<String> call() throws VcsException { + MercurialCommandLine cmd = createCommandLine(); + cmd.addParameters("resolve", "--no-status", "--list"); + CommandResult result = runCommand(cmd); + String stdout = result.getStdout(); + if (stdout.length() == 0) + return emptyList(); + List<String> unresolvedFiles = new ArrayList<String>(); + for (String line: stdout.split("[\r\n]+")) { + unresolvedFiles.add(line); + } + return unresolvedFiles; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/TagsCommand.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,30 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial.command; + +import jetbrains.buildServer.vcs.VcsException; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.Map; + +public class TagsCommand extends BranchesCommand { + + public TagsCommand(@NotNull CommandSettings commandSettings, + @NotNull String hgPath, + @NotNull File workingDir, + @NotNull AuthSettings authSettings) { + super(commandSettings, hgPath, workingDir, authSettings); + } + + @NotNull + @Override + protected String getBranchesCommand() { + return "tags"; + } + + @Override + public Map<String, String> call() throws VcsException { + Map<String, String> raw = super.call(); + raw.remove("tip"); + return raw; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/exception/MergeConflictException.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,9 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception; + +import jetbrains.buildServer.vcs.VcsException; + +public class MergeConflictException extends VcsException { + public MergeConflictException() { + super("Merge conflict"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/exception/MergeWithWorkingDirAncestor.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,11 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception; + +import jetbrains.buildServer.vcs.VcsException; + +public class MergeWithWorkingDirAncestor extends VcsException { + + public MergeWithWorkingDirAncestor() { + super("Merging with a working directory ancestor"); + } + +}
--- a/mercurial-server-tc/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialExtensionRegistry.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server-tc/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialExtensionRegistry.java Tue Oct 01 12:52:11 2013 +0400 @@ -8,6 +8,6 @@ public MercurialExtensionRegistry(@NotNull MercurialVcsSupport vcs, @NotNull Collection<MercurialServerExtension> extensions) { - vcs.setExtensions(extensions); + vcs.addExtensions(extensions); } }
--- a/mercurial-server/resources/buildServerResources/fastlog.template Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server/resources/buildServerResources/fastlog.template Tue Oct 01 12:52:11 2013 +0400 @@ -1,8 +1,10 @@ header = '<?xml version="1.0"?>\n<log>\n' footer = '</log>\n' -changeset = '<logentry revision="{rev}" shortnode="{node|short}">\n{parents}<author original="{author|xmlescape}"/>\n<date>{date|date|xmlescape}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n<paths>\n{files}</paths>\n</logentry>\n' +changeset = '<logentry revision="{rev}" shortnode="{node|short}" branch="{branches}">\n{parents}<author original="{author|xmlescape}"/>\n<date>{date|date|xmlescape}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n<paths>\n{files}</paths>\n</logentry>\n' file = '<path action="M">{file|xmlescape}</path>\n' parent = '<parent revision="{rev}" shortnode="{node|short}"/>\n' + +branch = '{branch|xmlescape}'
--- a/mercurial-server/resources/buildServerResources/log.no.files.template Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server/resources/buildServerResources/log.no.files.template Tue Oct 01 12:52:11 2013 +0400 @@ -1,6 +1,6 @@ header = '<?xml version="1.0"?>\n<log>\n' footer = '</log>\n' -changeset = '<logentry revision="{rev}" shortnode="{node|short}">\n{parents}<author original="{author|xmlescape}"/>\n<date>{date|date|xmlescape}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n</logentry>\n' - +changeset = '<logentry revision="{rev}" shortnode="{node|short}" branch="{branches}">\n{parents}<author original="{author|xmlescape}"/>\n<date>{date|date|xmlescape}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n</logentry>\n' parent = '<parent revision="{rev}" node="{node}" shortnode="{node|short}"/>\n' +branch = '{branch|xmlescape}'
--- a/mercurial-server/resources/buildServerResources/log.template Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server/resources/buildServerResources/log.template Tue Oct 01 12:52:11 2013 +0400 @@ -1,11 +1,12 @@ header = '<?xml version="1.0"?>\n<log>\n' footer = '</log>\n' -changeset = '<logentry revision="{rev}" shortnode="{node|short}">\n{parents}<author original="{author|xmlescape}"/>\n<date>{date|date|xmlescape}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n<paths>\n{file_adds}{file_dels}{file_mods}</paths>\n</logentry>\n' +changeset = '<logentry revision="{rev}" shortnode="{node|short}" branch="{branches}">\n{parents}<author original="{author|xmlescape}"/>\n<date>{date|date|xmlescape}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n<paths>\n{file_adds}{file_dels}{file_mods}</paths>\n</logentry>\n' file_add = '<path action="A">{file_add|xmlescape}</path>\n' file_mod = '<path action="M">{file_mod|xmlescape}</path>\n' file_del = '<path action="R">{file_del|xmlescape}</path>\n' parent = '<parent revision="{rev}" shortnode="{node|short}"/>\n' +branch = '{branch|xmlescape}'
--- a/mercurial-server/resources/buildServerResources/mercurialSettings.jsp Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server/resources/buildServerResources/mercurialSettings.jsp Tue Oct 01 12:52:11 2013 +0400 @@ -27,13 +27,20 @@ </td> </tr> <bs:branchSpecTableRow/> - <tr> + <tr class="advancedSetting"> + <th><label for="reportTagRevisions">Use tags as branches:</label></th> + <td> + <props:checkboxProperty name="useTagsAsBranches"/> + <div class="smallNote" style="margin: 0">If enabled tags can be used in branch specification</div> + </td> + </tr> + <tr class="advancedSetting"> <th><label for="serverClonePath">Clone repository to: </label></th> <td><props:textProperty name="serverClonePath" className="longField"/> <div class="smallNote" style="margin: 0;">Provide path to a parent directory on TeamCity server where a cloned repository should be created (applicable to "Automatically on server" checkout mode only). Leave blank to use default path.</div> </td> </tr> - <tr> + <tr class="advancedSetting"> <th><label for="detectSubrepoChanges">Detect subrepo changes: </label></th> <td> <props:checkboxProperty name="detectSubrepoChanges"/> @@ -42,13 +49,13 @@ </c:if> </td> </tr> - <tr> + <tr class="advancedSetting"> <th><label for="tagUsername">Username for tags: </label></th> <td><props:textProperty name="tagUsername"/> <div class="smallNote" style="margin: 0;">Format: User Name <email></div> </td> </tr> - <tr> + <tr class="advancedSetting"> <th><label for="uncompressedTransfer">Use uncompressed transfer: </label></th> <td><props:checkboxProperty name="uncompressedTransfer"/> <div class="smallNote" style="margin: 0;">Uncompressed transfer is faster for repositories in the LAN.</div>
--- a/mercurial-server/src/META-INF/build-server-plugin-mercurial.xml Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server/src/META-INF/build-server-plugin-mercurial.xml Tue Oct 01 12:52:11 2013 +0400 @@ -11,4 +11,8 @@ <bean id="testConnection" class="jetbrains.buildServer.buildTriggers.vcs.mercurial.HgTestConnectionSupport" /> <bean id="commandSettingsFactory" class="jetbrains.buildServer.buildTriggers.vcs.mercurial.ServerCommandSettingsFactory"/> <bean id="cleaner" class="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialCleaner"/> + <bean id="mergeSupport" class="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialMergeSupport"/> + + <bean class="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialCommitsInfoBuilderSupport"/> + <bean class="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialModificationInfoBuilder"/> </beans>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CheckoutRepository.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,178 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; +import jetbrains.buildServer.vcs.VcsException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.Map; + +import static jetbrains.buildServer.util.FileUtil.delete; + +/** + * Repository checkout which uses mirrors (updates them first) + * and supports subrepos. + */ +public class CheckoutRepository { + + private final MirrorManager myMirrorManager; + private final HgRepoFactory myHgRepoFactory; + private final int myPullTimeout; + private boolean myGlobalTagsAsBranches; + private final HgVcsRoot myRoot; + private final File myWorkingDir; + private String myRevision; + private String myBranch; + + CheckoutRepository(@NotNull MirrorManager mirrorManager, + @NotNull HgRepoFactory hgRepoFactory, + int pullTimeout, + boolean globalTagsAsBranches, + @NotNull HgVcsRoot root, + @NotNull File workingDir) { + myMirrorManager = mirrorManager; + myHgRepoFactory = hgRepoFactory; + myPullTimeout = pullTimeout; + myRoot = root; + myWorkingDir = workingDir; + } + + public CheckoutRepository setRevision(String revision) { + myRevision = revision; + return this; + } + + public CheckoutRepository setBranch(String branch) { + myBranch = branch; + return this; + } + + public void checkout() throws VcsException { + checkout(myRoot, myWorkingDir, myRevision); + } + + private void checkout(@NotNull HgVcsRoot root, + @NotNull File workingDir, + @Nullable String revision) throws VcsException { + updateRepository(root, workingDir, revision); + if (revision == null && myBranch != null) { + HgRepo repo = myHgRepoFactory.createRepo(root, workingDir); + boolean includeTags = myGlobalTagsAsBranches && root.useTagsAsBranches(); + Map<String, String> revisions = repo.getBranchRevisions(true, includeTags); + revision = revisions.get(myBranch); + } + if (revision == null) + return; + updateSubrepos(root, workingDir, revision); + updateWorkingDir(root, workingDir, revision); + } + + + private void updateRepository(@NotNull HgVcsRoot root, + @NotNull File workingDir, + @Nullable String revision) throws VcsException { + HgRepo repo = myHgRepoFactory.createRepo(root, workingDir); + if (revision != null && repo.containsRevision(revision)) + return; + + updateMirror(root, revision); + String mirrorUrl = getMirrorUrl(root); + + if (repo.isValidRepository()) { + repo.pull().fromRepository(mirrorUrl) + .withTimeout(myPullTimeout) + .call(); + } else { + repo.doClone().fromRepository(mirrorUrl) + .setUpdateWorkingDir(false) + .call(); + + repo.setDefaultPath(root.getRepository()); + } + } + + + private void updateWorkingDir(@NotNull HgVcsRoot root, + @NotNull File workingDir, + @NotNull String revision) throws VcsException { + HgRepo repo = myHgRepoFactory.createRepo(root, workingDir); + repo.update().toRevision(revision).call(); + } + + + private void updateSubrepos(@NotNull HgVcsRoot root, + @NotNull File workingDir, + @Nullable String revision) throws VcsException { + HgRepo repo = myHgRepoFactory.createRepo(root, workingDir); + if (!repo.hasSubreposAtRevision(revision)) + return; + + String workingDirRevision = repo.getWorkingDirRevision(); + Map<String, SubRepo> workingDirSubrepos = repo.getSubrepositories(workingDirRevision); + Map<String, SubRepo> subrepos = repo.getSubrepositories(revision); + for (Map.Entry<String, SubRepo> entry : subrepos.entrySet()) { + String path = entry.getKey(); + SubRepo subrepoConfig = entry.getValue(); + SubRepo workingDirSubrepo = workingDirSubrepos.get(path); + if (workingDirSubrepo != null && subrepoConfig.hasDifferentUrlThan(workingDirSubrepo)) + delete(subrepoConfigDir(repo, subrepoConfig)); + + File subrepoDir = new File(workingDir, subrepoConfig.path()); + String subrepoUrl; + try { + subrepoUrl = subrepoConfig.resolveUrl(root.getRepository()); + if (subrepoConfig.vcsType() == SubRepo.VcsType.hg && !isRelativeUrl(subrepoUrl)) { + HgVcsRoot subrepoRoot = root.withUrl(subrepoUrl); + updateRepository(subrepoRoot, subrepoDir, subrepoConfig.revision()); + } + } catch (URISyntaxException e) { + subrepoUrl = subrepoConfig.url(); + } + + updateSubrepos(root.withUrl(subrepoUrl), subrepoDir, subrepoConfig.revision()); + } + } + + + private boolean isRelativeUrl(@NotNull String url) { + return url.startsWith("."); + } + + + private File subrepoConfigDir(@NotNull HgRepo parentRepo, @NotNull SubRepo subrepo) { + return new File(parentRepo.getWorkingDir(), subrepo.path()); + } + + + private void updateMirror(@NotNull HgVcsRoot root, @Nullable String revision) throws VcsException { + String url = root.getRepository(); + File mirrorDir = myMirrorManager.getMirrorDir(url); + HgRepo repo = myHgRepoFactory.createRepo(root, mirrorDir); + if (revision != null && repo.containsRevision(revision)) { + return; + } + + if (repo.isValidRepository()) { + repo.pull().fromRepository(root.getRepository()) + .withTimeout(myPullTimeout) + .call(); + } else { + repo.doClone().fromRepository(root.getRepository()) + .setUpdateWorkingDir(false) + .useUncompressedTransfer(root.isUncompressedTransfer()) + .call(); + repo.setDefaultPath(root.getRepository()); + } + } + + private String getMirrorUrl(@NotNull HgVcsRoot root) throws VcsException { + try { + return myMirrorManager.getMirrorDir(root.getRepository()).getCanonicalPath(); + } catch (IOException e) { + throw new VcsException(e); + } + } +}
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgVcsRootFactory.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgVcsRootFactory.java Tue Oct 01 12:52:11 2013 +0400 @@ -21,6 +21,7 @@ } + @NotNull public HgVcsRoot createHgRoot(@NotNull VcsRoot root) throws VcsException { HgVcsRoot hgRoot = new HgVcsRoot(root); String customClonePath = hgRoot.getCustomClonePath();
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCollectChangesPolicy.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCollectChangesPolicy.java Tue Oct 01 12:52:11 2013 +0400 @@ -43,9 +43,8 @@ public RepositoryStateData getCurrentState(@NotNull VcsRoot root) throws VcsException { HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); myVcs.syncRepository(hgRoot); - Map<String, String> revisions = new HashMap<String, String>(); - revisions.putAll(getBookmarkRevisions(hgRoot)); - revisions.putAll(getBranchesRevisions(hgRoot)); + boolean includeTags = myConfig.useTagsAsBranches() && hgRoot.useTagsAsBranches(); + Map<String, String> revisions = myVcs.createRepo(hgRoot).getBranchRevisions(myConfig.bookmarksEnabled(), includeTags); String defaultBranchName = hgRoot.getBranchName(); if (revisions.get(defaultBranchName) == null) { throw new VcsException("Cannot find revision of the default branch '" + @@ -56,25 +55,6 @@ @NotNull - private Map<String, String> getBranchesRevisions(@NotNull HgVcsRoot root) throws VcsException { - HgRepo repo = myVcs.createRepo(root); - return repo.branches().call(); - } - - - @NotNull - private Map<String, String> getBookmarkRevisions(@NotNull HgVcsRoot root) throws VcsException { - ServerHgRepo repo = myVcs.createRepo(root); - if (!myConfig.bookmarksEnabled()) - return emptyMap(); - HgVersion version = repo.version().call(); - if (!version.isEqualsOrGreaterThan(BookmarksCommand.REQUIRED_HG_VERSION)) - return emptyMap(); - return repo.bookmarks().call(); - } - - - @NotNull public List<ModificationData> collectChanges(@NotNull VcsRoot fromRoot, @NotNull RepositoryStateData fromState, @NotNull VcsRoot toRoot, @@ -170,11 +150,11 @@ } - private List<ModificationData> collectChanges(@NotNull OperationContext ctx, - @NotNull VcsRoot root, - @NotNull Collection<String> fromVersion, - @Nullable String currentVersion, - @NotNull CheckoutRules checkoutRules) throws VcsException { + public List<ModificationData> collectChanges(@NotNull OperationContext ctx, + @NotNull VcsRoot root, + @NotNull Collection<String> fromVersion, + @Nullable String currentVersion, + @NotNull CheckoutRules checkoutRules) throws VcsException { HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); ctx.syncRepository(hgRoot); List<ModificationData> result = new ArrayList<ModificationData>(); @@ -392,7 +372,7 @@ ServerHgRepo repo = myVcs.createRepo(ctx, root); SubrepoRevisionAttributesBuilder attrBuilder = new SubrepoRevisionAttributesBuilder(); for (SubRepo s : repo.getSubrepositories(m).values()) { - attrBuilder.addSubrepo(new SubrepoConfig(root) + attrBuilder.addSubrepo(new SubrepoConfig(mainRoot) .setSubrepoPath(ctx.getStringFromPool(root.expandSubrepoPath(s.path()))) .setSubrepoRootParamDiff(Constants.REPOSITORY_PROP, ctx.getStringFromPool(s.resolveUrl(root.getRepository()))) .setSubrepoRootParamDiff("teamcity.internal.subrepo", "true")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCommitsInfoBuilderSupport.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,75 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.ChangeSet; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.ChangeSetRevision; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; +import jetbrains.buildServer.vcs.*; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.command.LogCommand.ZERO_PARENT_ID; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.command.LogCommand.ZERO_PARENT_SHORT_ID; + +/** + * Created 30.09.13 13:05 + * + * @author Eugene Petrenko (eugene.petrenko@jetbrains.com) + */ +public class MercurialCommitsInfoBuilderSupport implements CommitsInfoBuilder, MercurialServerExtension { + private final MercurialVcsSupport mySupport; + private final HgVcsRootFactory myHgVcsRootFactory; + + public MercurialCommitsInfoBuilderSupport(@NotNull MercurialVcsSupport vcs, + @NotNull HgVcsRootFactory vcsRootFactory) { + vcs.addExtension(this); + mySupport = vcs; + myHgVcsRootFactory = vcsRootFactory; + } + + + @NotNull + public List<CommitDataBean> collectCommits(@NotNull VcsRoot root, + @NotNull CheckoutRules rules) throws VcsException { + final HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); + final ServerHgRepo repo = mySupport.createRepo(hgRoot); + mySupport.syncRepository(hgRoot); + + final Map<String, CommitDataBean> commitToBean = processChanges(repo); + + //collect tags info + Map<String, String> tags = repo.tags().call(); + for (Map.Entry<String, String> e : tags.entrySet()) { + CommitDataBean bean = commitToBean.get(e.getValue()); + if (bean != null) bean.addTag(e.getKey()); + } + + return new ArrayList<CommitDataBean>(commitToBean.values()); + } + + @NotNull + private Map<String, CommitDataBean> processChanges(@NotNull ServerHgRepo repo) throws VcsException { + final List<ChangeSet> tip = repo.logNoFiles() + .showCommitsFromAllBranches() + .call(); + + final Map<String, CommitDataBean> result = new HashMap<String, CommitDataBean>(); + for (ChangeSet set : tip) { + final CommitDataBean bean = new CommitDataBean(set.getId(), set.getFullVersion(), set.getTimestamp()); + for (ChangeSetRevision p : set.getParents()) { + final String commitId = p.getId(); + + if (ZERO_PARENT_ID.equals(commitId)) continue; + if (ZERO_PARENT_SHORT_ID.equals(commitId)) continue; + bean.addParentRevision(commitId); + } + bean.addBranch(set.getBranch()); + result.put(bean.getVersion(), bean); + } + + return result; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialMergeSupport.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,134 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import com.intellij.openapi.diagnostic.Logger; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.MergeConflictException; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.MergeWithWorkingDirAncestor; +import jetbrains.buildServer.vcs.*; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.HgFileUtil.deleteDir; + +public class MercurialMergeSupport implements MergeSupport, MercurialServerExtension { + + private final static Logger LOG = Logger.getInstance(MercurialMergeSupport.class.getName()); + + private final MirrorManager myMirrorManager; + private final ServerPluginConfig myConfig; + private final HgVcsRootFactory myHgVcsRootFactory; + private final HgRepoFactory myHgRepoFactory; + + public MercurialMergeSupport(@NotNull MercurialVcsSupport vcs, + @NotNull MirrorManager mirrorManager, + @NotNull ServerPluginConfig config, + @NotNull HgVcsRootFactory vcsRootFactory, + @NotNull HgRepoFactory hgRepoFactory) { + vcs.addExtension(this); + myMirrorManager = mirrorManager; + myConfig = config; + myHgVcsRootFactory = vcsRootFactory; + myHgRepoFactory = hgRepoFactory; + } + + @NotNull + public Map<MergeTask, MergeResult> tryMerge(@NotNull VcsRoot root, @NotNull List<MergeTask> tasks, @NotNull MergeOptions options) throws VcsException { + File tmpDir = null; + try { + tmpDir = HgFileUtil.createTempDir(); + HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); + HgRepo repo = myHgRepoFactory.createRepo(hgRoot, tmpDir); + Map<MergeTask, MergeResult> results = new HashMap<MergeTask, MergeResult>(); + for (MergeTask task : tasks) { + MergeResult result = new MergeResult(); + try { + new CheckoutRepository(myMirrorManager, myHgRepoFactory, myConfig.getPullTimeout(), myConfig.useTagsAsBranches(), hgRoot, tmpDir) + .setRevision(task.getDestinationRevision()).checkout(); + repo.merge().revision(task.getSourceRevision()).call(); + } catch (MergeConflictException e) { + result.setSuccess(false); + result.setConflicts(detectConflicts(hgRoot, "", repo)); + } catch (MergeWithWorkingDirAncestor e) { + //ignore + } catch (VcsException e) { + result.setSuccess(false); + } finally { + repo.update().toRevision(task.getDestinationRevision()).call(); + } + results.put(task, result); + } + return results; + } catch (Exception e) { + if (e instanceof VcsException) + throw (VcsException) e; + throw new VcsException(e); + } finally { + deleteDir(tmpDir, LOG); + } + } + + + @NotNull + public MergeResult merge(@NotNull VcsRoot root, + @NotNull String srcRevision, + @NotNull String dstBranch, + @NotNull String message, + @NotNull MergeOptions options) throws VcsException { + File tmpDir = null; + MergeResult mergeResult = new MergeResult(); + try { + tmpDir = HgFileUtil.createTempDir(); + HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); + + new CheckoutRepository(myMirrorManager, myHgRepoFactory, myConfig.getPullTimeout(), myConfig.useTagsAsBranches(), hgRoot, tmpDir) + .setBranch(dstBranch).checkout(); + + HgRepo repo = myHgRepoFactory.createRepo(hgRoot, tmpDir); + try { + repo.merge().revision(srcRevision).call(); + } catch (MergeConflictException e) { + mergeResult.setSuccess(false); + mergeResult.setConflicts(detectConflicts(hgRoot, "", repo)); + return mergeResult; + } catch (MergeWithWorkingDirAncestor e) { + return mergeResult; + } + + repo.commit().message(message).call(); + + repo.push().toRepository(hgRoot.getRepository()).call(); + return mergeResult; + } catch (Exception e) { + if (e instanceof VcsException) + throw (VcsException) e; + throw new VcsException(e); + } finally { + deleteDir(tmpDir, LOG); + } + } + + + private List<String> detectConflicts(@NotNull HgVcsRoot root, @NotNull String prefix, @NotNull HgRepo repo) throws VcsException { + List<String> conflicts = new ArrayList<String>(); + for (String conflict : repo.resolve().call()) { + conflicts.add(prefix + conflict); + } + + List<String> parents = repo.parents().call(); + if (parents.isEmpty()) + return conflicts; + + Map<String, SubRepo> subrepos = repo.getSubrepositories(parents.get(0)); + for (SubRepo subrepo : subrepos.values()) { + HgVcsRoot subrepoRoot = root.withUrl(subrepo.url()); + HgRepo hgSubrepo = myHgRepoFactory.createRepo(subrepoRoot, new File(repo.getWorkingDir(), subrepo.path())); + conflicts.addAll(detectConflicts(subrepoRoot, prefix + subrepo.path() + "/", hgSubrepo)); + } + return conflicts; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialModificationInfoBuilder.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,59 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; +import jetbrains.buildServer.vcs.*; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static java.util.Collections.emptyList; + +public class MercurialModificationInfoBuilder implements ModificationInfoBuilder, MercurialServerExtension { + + private final MercurialVcsSupport myVcs; + private final HgVcsRootFactory myHgVcsRootFactory; + private final RepoFactory myRepoFactory; + private final HgPathProvider myHgPathProvider; + + public MercurialModificationInfoBuilder(@NotNull MercurialVcsSupport vcs, + @NotNull HgVcsRootFactory hgVcsRootFactory, + @NotNull RepoFactory repoFactory, + @NotNull HgPathProvider hgPathProvider) { + myVcs = vcs; + myHgVcsRootFactory = hgVcsRootFactory; + myRepoFactory = repoFactory; + myHgPathProvider = hgPathProvider; + myVcs.addExtension(this); + } + + @NotNull + public List<ModificationData> fetchModificationInfo(@NotNull VcsRoot root, + @NotNull RepositoryStateData state, + @NotNull CheckoutRules checkoutRules) throws VcsException { + HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); + myVcs.syncRepository(hgRoot); + Set<String> prevRevisions = getPrevRevisions(hgRoot, state); + if (prevRevisions.isEmpty()) + return emptyList(); + OperationContext ctx = new OperationContext(myVcs, myRepoFactory, myHgPathProvider, prevRevisions, state); + List<ModificationData> changes = new ArrayList<ModificationData>(); + for (String revision : state.getBranchRevisions().values()) { + changes.addAll(myVcs.getCollectChangesPolicy().collectChanges(ctx, root, prevRevisions, revision, checkoutRules)); + } + return changes; + } + + + @NotNull + private Set<String> getPrevRevisions(@NotNull HgVcsRoot root, @NotNull RepositoryStateData state) throws VcsException { + Set<String> prevRevisions = new HashSet<String>(); + HgRepo repo = myVcs.createRepo(root); + for (String revision : state.getBranchRevisions().values()) { + prevRevisions.addAll(repo.parents().ofRevision(revision).call()); + } + return prevRevisions; + } +}
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Tue Oct 01 12:52:11 2013 +0400 @@ -21,7 +21,10 @@ import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.AbandonedTransactionFound; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.UnrelatedRepositoryException; import jetbrains.buildServer.log.Loggers; -import jetbrains.buildServer.serverSide.*; +import jetbrains.buildServer.serverSide.InvalidProperty; +import jetbrains.buildServer.serverSide.PropertiesProcessor; +import jetbrains.buildServer.serverSide.ServerListener; +import jetbrains.buildServer.serverSide.ServerListenerAdapter; import jetbrains.buildServer.util.EventDispatcher; import jetbrains.buildServer.util.FileUtil; import jetbrains.buildServer.util.cache.ResetCacheRegister; @@ -37,7 +40,6 @@ import java.net.URISyntaxException; import java.util.*; -import static java.util.Collections.emptyMap; import static jetbrains.buildServer.buildTriggers.vcs.mercurial.HgFileUtil.deleteDir; /** @@ -61,7 +63,7 @@ private final FileFilter myAcceptAllFilter = new AcceptAllFilter(); private final HgTestConnectionSupport myTestConnection; private final SubrepoCheckoutRulesProvider mySubrepoCheckoutRulesProvider; - private Collection<MercurialServerExtension> myExtensions; + private final Collection<MercurialServerExtension> myExtensions = new ArrayList<MercurialServerExtension>(); public MercurialVcsSupport(@NotNull final EventDispatcher<ServerListener> dispatcher, @NotNull final ResetCacheRegister resetCacheHandlerManager, @@ -89,8 +91,12 @@ logUsedHg(); } - public void setExtensions(@NotNull Collection<MercurialServerExtension> extensions) { - myExtensions = extensions; + public void addExtensions(@NotNull Collection<MercurialServerExtension> extensions) { + myExtensions.addAll(extensions); + } + + public void addExtension(@NotNull MercurialServerExtension extension) { + myExtensions.add(extension); } private void logUsedHg() { @@ -498,6 +504,14 @@ public void buildPatch(@NotNull VcsRoot root, @Nullable String fromVersion, @NotNull String toVersion, @NotNull PatchBuilder builder, @NotNull CheckoutRules checkoutRules) throws IOException, VcsException { HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); + buildPatch(hgRoot, fromVersion, toVersion, builder, checkoutRules); + } + + public void buildPatch(@NotNull HgVcsRoot hgRoot, + @Nullable String fromVersion, + @NotNull String toVersion, + @NotNull PatchBuilder builder, + @NotNull CheckoutRules checkoutRules) throws IOException, VcsException { syncRepository(hgRoot); ChangeSet to = new ChangeSet(toVersion); if (fromVersion == null) { @@ -571,7 +585,7 @@ return label.replace(':', '_').replace('\r', '_').replace('\n', '_'); } - File getWorkingDir(HgVcsRoot root) { + public File getWorkingDir(HgVcsRoot root) { File customDir = root.getCustomWorkingDir(); return customDir != null ? customDir : myMirrorManager.getMirrorDir(root.getRepository()); } @@ -623,7 +637,7 @@ } - private HgRepo createRepo(@NotNull HgVcsRoot root, @NotNull File customDir) throws VcsException { + public HgRepo createRepo(@NotNull HgVcsRoot root, @NotNull File customDir) throws VcsException { return myRepoFactory.create(customDir, myHgPathProvider.getHgPath(root), root.getAuthSettings()); } @@ -646,12 +660,10 @@ @Override @Nullable protected <T extends VcsExtension> T getVcsCustomExtension(@NotNull final Class<T> extensionClass) { - if (myExtensions == null) - return null; for (MercurialServerExtension e : myExtensions) { if (extensionClass.isInstance(e)) return extensionClass.cast(e); } - return null; + return super.getVcsCustomExtension(extensionClass); } }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/OperationContext.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/OperationContext.java Tue Oct 01 12:52:11 2013 +0400 @@ -17,13 +17,14 @@ import java.util.*; import static java.util.Collections.singleton; +import static jetbrains.buildServer.util.CollectionsUtil.setOf; public class OperationContext { private final MercurialVcsSupport myVcs; private final RepoFactory myRepoFactory; private final HgPathProvider myHgPathProvider; - private final RepositoryStateData myFromState; + private final Set<String> myUninterestingRevisions; private final RepositoryStateData myToState; private final Map<VcsRootKey, DAG<String>> myDags = new HashMap<VcsRootKey, DAG<String>>(); private Set<File> mySyncedDirs = new HashSet<File>(); @@ -39,11 +40,7 @@ @NotNull HgPathProvider hgPathProvider, @NotNull RepositoryStateData fromState, @NotNull RepositoryStateData toState) { - myVcs = vcs; - myRepoFactory = repoFactory; - myHgPathProvider = hgPathProvider; - myFromState = fromState; - myToState = toState; + this(vcs, repoFactory, hgPathProvider, new HashSet<String>(fromState.getBranchRevisions().values()), toState); } public OperationContext(@NotNull MercurialVcsSupport vcs, @@ -51,7 +48,19 @@ @NotNull HgPathProvider hgPathProvider, @NotNull String fromVersion, @NotNull String toVersion) { - this(vcs, repoFactory, hgPathProvider, RepositoryStateData.createSingleVersionState(fromVersion), RepositoryStateData.createSingleVersionState(toVersion)); + this(vcs, repoFactory, hgPathProvider, setOf(fromVersion), RepositoryStateData.createSingleVersionState(toVersion)); + } + + public OperationContext(@NotNull MercurialVcsSupport vcs, + @NotNull RepoFactory repoFactory, + @NotNull HgPathProvider hgPathProvider, + @NotNull Collection<String> fromVersions, + @NotNull RepositoryStateData toState) { + myVcs = vcs; + myRepoFactory = repoFactory; + myHgPathProvider = hgPathProvider; + myToState = toState; + myUninterestingRevisions = new HashSet<String>(fromVersions); } public void syncRepository(@NotNull final HgVcsRoot root) throws VcsException { @@ -197,7 +206,7 @@ myDags.put(rootKey, dag); } if (dag.containsNode(toRevision)) { - FindIntervalVisitor visitor = new FindIntervalVisitor(dag, myFromState.getBranchRevisions().values()); + FindIntervalVisitor visitor = new FindIntervalVisitor(dag, myUninterestingRevisions); dag.breadthFirstSearch(toRevision, visitor); fromRevisions.addAll(visitor.getEndpoints()); } else { @@ -224,6 +233,10 @@ super(repositoryUrl, subrepoPath); } + private static VcsRootKey create(@NotNull HgVcsRoot root) { + return new VcsRootKey(root.getProperty(Constants.REPOSITORY_PROP), root.getProperty("teamcity.internal.subrepo.path")); + } + private static VcsRootKey create(@NotNull VcsRoot root) { return new VcsRootKey(root.getProperty(Constants.REPOSITORY_PROP), root.getProperty("teamcity.internal.subrepo.path")); }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/RepoFactory.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/RepoFactory.java Tue Oct 01 12:52:11 2013 +0400 @@ -2,6 +2,7 @@ import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.AuthSettings; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CommandSettingsFactory; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; import jetbrains.buildServer.util.FileUtil; import jetbrains.buildServer.vcs.VcsException; import org.jetbrains.annotations.NotNull; @@ -15,19 +16,23 @@ /** * @author dmitry.neverov */ -public class RepoFactory { +public class RepoFactory implements HgRepoFactory { protected final ServerPluginConfig myConfig; protected final CommandSettingsFactory myCommandSettingsFactory; + protected final HgPathProvider myHgPathProvider; protected final MercurialLogTemplate myLogTemplate = new MercurialLogTemplate("/buildServerResources/log.template", "hg.log.template"); protected final MercurialLogTemplate myLogNoFilesTemplate = new MercurialLogTemplate("/buildServerResources/log.no.files.template", "hg.short.log.template"); protected final MercurialLogTemplate myDagTemplate = new MercurialLogTemplate("/buildServerResources/dag.template", "hg.dag.template"); protected final MercurialLogTemplate myFastLogTemplate = new MercurialLogTemplate("/buildServerResources/fastlog.template", "hg.fastlog.template"); - public RepoFactory(@NotNull ServerPluginConfig config, @NotNull CommandSettingsFactory commandSettingsFactory) throws IOException { + public RepoFactory(@NotNull ServerPluginConfig config, + @NotNull CommandSettingsFactory commandSettingsFactory, + @NotNull HgPathProvider hgPathProvider) throws IOException { myConfig = config; myCommandSettingsFactory = commandSettingsFactory; + myHgPathProvider = hgPathProvider; } @NotNull @@ -41,6 +46,10 @@ myFastLogTemplate.getTemplate()); } + public HgRepo createRepo(@NotNull HgVcsRoot root, @NotNull File workingDir) throws VcsException { + return create(workingDir, myHgPathProvider.getHgPath(root), root.getAuthSettings()); + } + public void dispose() { myLogTemplate.dispose(); myLogNoFilesTemplate.dispose();
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgRepo.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgRepo.java Tue Oct 01 12:52:11 2013 +0400 @@ -58,6 +58,11 @@ return new LogCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir, myAuthSettings).withTemplate(myLogTemplate); } + @NotNull + public LogCommand logNoFiles() { + return log().withTemplate(myLogNoFilesTemplate); + } + public LogCommand log(@NotNull HgVcsRoot root) { File template = root.isSubrepo() && !myConfig.reportSubrepoChangesFileStatus() ? myFastLogTemplate : myLogTemplate; return new LogCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir, myAuthSettings).withTemplate(template);
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfig.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfig.java Tue Oct 01 12:52:11 2013 +0400 @@ -3,8 +3,6 @@ import org.jetbrains.annotations.Nullable; import org.quartz.CronExpression; -import java.util.Set; - /** * @author dmitry.neverov */ @@ -23,6 +21,8 @@ public boolean bookmarksEnabled(); + public boolean useTagsAsBranches(); + public int getMaxDagNodesCount(); public int getLogOutputLimit();
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigImpl.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigImpl.java Tue Oct 01 12:52:11 2013 +0400 @@ -67,6 +67,10 @@ return TeamCityProperties.getBooleanOrTrue("teamcity.hg.enableBookmarks"); } + public boolean useTagsAsBranches() { + return TeamCityProperties.getBooleanOrTrue("teamcity.hg.useTagsAsBranches"); + } + public long getMirrorExpirationTimeoutMillis() { int days = TeamCityProperties.getInteger("teamcity.hg.mirrorExpirationTimeoutDays", 7); return days * Dates.ONE_DAY;
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentMirrorCleanerTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentMirrorCleanerTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -1,16 +1,12 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial; -import com.intellij.openapi.diagnostic.Logger; -import jetbrains.buildServer.TempFiles; import jetbrains.buildServer.agent.*; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.TestCommandSettingsFactory; -import jetbrains.buildServer.log.Log4jFactory; import jetbrains.buildServer.vcs.*; import jetbrains.buildServer.vcs.impl.VcsRootImpl; import org.jetbrains.annotations.NotNull; import org.jmock.Expectations; import org.jmock.Mockery; -import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -26,13 +22,8 @@ * @author dmitry.neverov */ @Test -public class AgentMirrorCleanerTest { +public class AgentMirrorCleanerTest extends BaseMercurialTestCase { - static { - Logger.setFactory(new Log4jFactory()); - } - - private TempFiles myTempFiles = new TempFiles(); private Mockery myContext; private MercurialAgentSideVcsSupport myVcsSupport; private AgentMirrorCleaner myCleaner; @@ -43,6 +34,7 @@ @BeforeMethod public void setUp() throws Exception { + super.setUp(); myContext = new Mockery(); myWorkDir = myTempFiles.createTempDir(); @@ -53,10 +45,9 @@ }}); AgentPluginConfigImpl pluginConfig = new AgentPluginConfigImpl(agentConfig); - AgentHgPathProvider hgPathProvider = new AgentHgPathProvider(agentConfig); myMirrorManager = new MirrorManagerImpl(pluginConfig); - AgentRepoFactory repoFactory = new AgentRepoFactory(new TestCommandSettingsFactory()); - myVcsSupport = new MercurialAgentSideVcsSupport(pluginConfig, hgPathProvider, myMirrorManager, repoFactory); + AgentRepoFactory repoFactory = new AgentRepoFactory(new TestCommandSettingsFactory(), new AgentHgPathProvider(agentConfig)); + myVcsSupport = new MercurialAgentSideVcsSupport(pluginConfig, myMirrorManager, repoFactory); myCleaner = new AgentMirrorCleaner(myMirrorManager); myLogger = myContext.mock(BuildProgressLogger.class); myContext.checking(new Expectations() {{ @@ -65,11 +56,6 @@ }}); } - @AfterMethod - public void tearDown() { - myTempFiles.cleanup(); - } - public void should_add_cleaners_only_for_roots_not_used_in_build() throws Exception { //setup mirrors for 2 roots on an agent:
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -46,7 +46,7 @@ * Date: 30.07.2008 */ @Test -public class AgentSideCheckoutTest extends BaseMercurialTestCase { +public class AgentSideCheckoutTest extends BaseMercurialPatchTestCase { final static String HG_PATH_REFERENCE = "%" + HgDetector.AGENT_HG_PATH_PROPERTY + "%"; private MercurialAgentSideVcsSupport myVcsSupport; @@ -74,9 +74,8 @@ final AgentPluginConfigImpl pluginConfig = new AgentPluginConfigImpl(agentConfig); myVcsSupport = new MercurialAgentSideVcsSupport(pluginConfig, - new AgentHgPathProvider(agentConfig), new MirrorManagerImpl(pluginConfig), - new AgentRepoFactory(new TestCommandSettingsFactory())); + new AgentRepoFactory(new TestCommandSettingsFactory(), new AgentHgPathProvider(agentConfig))); myLogger = myContext.mock(BuildProgressLogger.class); myContext.checking(new Expectations() {{
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutWithSubreposTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/AgentSideCheckoutWithSubreposTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -1,7 +1,5 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial; -import com.intellij.openapi.diagnostic.Logger; -import jetbrains.buildServer.TempFiles; import jetbrains.buildServer.agent.AgentRunningBuild; import jetbrains.buildServer.agent.BuildAgentConfiguration; import jetbrains.buildServer.agent.BuildProgressLogger; @@ -9,7 +7,6 @@ import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.AuthSettings; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.TestCommandSettingsFactory; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.ConnectionRefusedException; -import jetbrains.buildServer.log.Log4jFactory; import jetbrains.buildServer.util.FileUtil; import jetbrains.buildServer.vcs.CheckoutRules; import jetbrains.buildServer.vcs.IncludeRule; @@ -39,9 +36,8 @@ * @author dmitry.neverov */ @Test -public class AgentSideCheckoutWithSubreposTest { +public class AgentSideCheckoutWithSubreposTest extends BaseMercurialTestCase { - private TempFiles myTempFiles = new TempFiles(); private File myOriginalRepositoriesParentDir; private File myWorkDir; private Mockery myContext; @@ -52,12 +48,9 @@ private File myDefaultWorkDir; private MirrorManagerImpl myMirrorManager; - static { - Logger.setFactory(new Log4jFactory()); - } - @BeforeMethod public void setUp() throws Exception { + super.setUp(); myProcesses = new ArrayList<Process>(); myOriginalRepositoriesParentDir = myTempFiles.createTempDir(); myDefaultWorkDir = new File(myOriginalRepositoriesParentDir, "agentWorkDir"); @@ -73,9 +66,8 @@ final AgentPluginConfigImpl pluginConfig = new AgentPluginConfigImpl(agentConfig); myMirrorManager = new MirrorManagerImpl(pluginConfig); myVcsSupport = new MercurialAgentSideVcsSupport(pluginConfig, - new AgentHgPathProvider(agentConfig), myMirrorManager, - new AgentRepoFactory(new TestCommandSettingsFactory())); + new AgentRepoFactory(new TestCommandSettingsFactory(), new AgentHgPathProvider(agentConfig))); myLogger = myContext.mock(BuildProgressLogger.class); myContext.checking(new Expectations() {{ @@ -86,7 +78,7 @@ @AfterMethod public void tearDown() { - myTempFiles.cleanup(); + super.tearDown(); for (Process p : myProcesses) { p.destroy(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/BaseMercurialPatchTestCase.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import jetbrains.buildServer.vcs.impl.VcsRootImpl; +import jetbrains.buildServer.vcs.patches.PatchTestCase; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; + +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.Util.copyRepository; + +/** + * @author Pavel.Sher + * Date: 31.07.2008 + */ +public abstract class BaseMercurialPatchTestCase extends PatchTestCase { + protected VcsRootImpl createVcsRoot(@NotNull String repPath) throws IOException { + File repository = copyRepository(myTempFiles, repPath); + return new VcsRootBuilder().withUrl(repository.getAbsolutePath()).build(); + } + + protected VcsRootImpl createVcsRoot(@NotNull String repPath, @NotNull String branchName) throws IOException { + File repository = copyRepository(myTempFiles, repPath); + return new VcsRootBuilder().withUrl(repository.getAbsolutePath()).withBranch(branchName).build(); + } + + protected String simpleRepo() { + return new File("mercurial-tests/testData/rep1").getAbsolutePath(); + } +}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/BaseMercurialTestCase.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/BaseMercurialTestCase.java Tue Oct 01 12:52:11 2013 +0400 @@ -1,62 +1,19 @@ -/* - * Copyright 2000-2011 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ package jetbrains.buildServer.buildTriggers.vcs.mercurial; import jetbrains.buildServer.TempFiles; -import jetbrains.buildServer.vcs.impl.VcsRootImpl; -import jetbrains.buildServer.vcs.patches.PatchTestCase; -import org.jetbrains.annotations.NotNull; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; -import java.io.File; -import java.io.IOException; - -import static jetbrains.buildServer.buildTriggers.vcs.mercurial.Util.copyRepository; - -/** - * @author Pavel.Sher - * Date: 31.07.2008 - */ -public abstract class BaseMercurialTestCase extends PatchTestCase { +public class BaseMercurialTestCase { protected TempFiles myTempFiles; - @Override @BeforeMethod - protected void setUp() throws Exception { - super.setUp(); + public void setUp() throws Exception { myTempFiles = new TempFiles(); } @AfterMethod - protected void tearDown() throws Exception { + public void tearDown() { myTempFiles.cleanup(); } - - protected VcsRootImpl createVcsRoot(@NotNull String repPath) throws IOException { - File repository = copyRepository(myTempFiles, repPath); - return new VcsRootBuilder().withUrl(repository.getAbsolutePath()).build(); - } - - protected VcsRootImpl createVcsRoot(@NotNull String repPath, @NotNull String branchName) throws IOException { - File repository = copyRepository(myTempFiles, repPath); - return new VcsRootBuilder().withUrl(repository.getAbsolutePath()).withBranch(branchName).build(); - } - - protected String simpleRepo() { - return new File("mercurial-tests/testData/rep1").getAbsolutePath(); - } }
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/BookmarksTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/BookmarksTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -1,8 +1,5 @@ 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.RepositoryStateData; import jetbrains.buildServer.vcs.VcsRoot; @@ -25,13 +22,8 @@ @RequiredHgVersion(min = "2.4") @Test(dataProviderClass = HgVersionConstraint.class, dataProvider = "installedHgVersion") -public class BookmarksTest { +public class BookmarksTest extends BaseMercurialTestCase { - static { - Logger.setFactory(new Log4jFactory()); - } - - private TempFiles myTempFiles; private File myRemoteRepository; private ServerPluginConfig myConfig; private MercurialVcsSupport myVcs; @@ -39,7 +31,7 @@ @BeforeMethod public void setUp() throws Exception { - myTempFiles = new TempFiles(); + super.setUp(); myRemoteRepository = myTempFiles.createTempDir(); myConfig = serverPluginConfig() .cachesDir(myTempFiles.createTempDir()) @@ -50,11 +42,6 @@ myRoot = vcsRoot().withUrl(myRemoteRepository.getAbsolutePath()).build(); } - @AfterMethod - public void tearDown() { - myTempFiles.cleanup(); - } - public void current_state_should_include_bookmarks(@NotNull HgVersion _) throws Exception { setupRemoteRepositoryWithTwoBookmarks();
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CleanupTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CleanupTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -26,9 +26,8 @@ * @author dmitry.neverov */ @Test -public class CleanupTest { +public class CleanupTest extends BaseMercurialTestCase { - private TempFiles myTempFiles; private File myCachesDir; private Cleanup myCleanup; private MirrorManager myMirrorManager; @@ -36,7 +35,7 @@ @BeforeMethod public void setUp() throws Exception { - myTempFiles = new TempFiles(); + super.setUp(); myCachesDir = myTempFiles.createTempDir(); ServerPluginConfig config = new ServerPluginConfigBuilder().cachesDir(myCachesDir).withMirrorExpirationTimeout(myMirrorExpirationTimeout).build(); @@ -45,11 +44,6 @@ myCleanup = new Cleanup(myMirrorManager, config); } - @AfterMethod - public void tearDown() { - myTempFiles.cleanup(); - } - public void cleanup_should_remove_directories_by_timestamp() throws Exception { final String url1 = "http://some.org/repository1";
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/CommitsInfoBuilderSupportTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,100 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import jetbrains.buildServer.TestLogger; +import jetbrains.buildServer.vcs.CheckoutRules; +import jetbrains.buildServer.vcs.CommitDataBean; +import jetbrains.buildServer.vcs.VcsException; +import jetbrains.buildServer.vcs.VcsRoot; +import jetbrains.vcs.api.CommitInfo; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +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; + +/** + * Created 30.09.13 13:07 + * + * @author Eugene Petrenko (eugene.petrenko@jetbrains.com) + */ +public class CommitsInfoBuilderSupportTest extends BaseMercurialTestCase { + private File myRemoteRepo; + private MercurialVcsSupport myVcs; + private MercurialCommitsInfoBuilderSupport mySupport; + + @Override + @BeforeMethod + public void setUp() throws Exception { + super.setUp(); + ServerPluginConfig pluginConfig = new ServerPluginConfigBuilder() +// .hgPath("hg") + .cachesDir(myTempFiles.createTempDir()) + .build(); + MercurialSupportBuilder mercurialBuilder = mercurialSupport().withConfig(pluginConfig); + myVcs = mercurialBuilder.build(); + mySupport = new MercurialCommitsInfoBuilderSupport(myVcs, mercurialBuilder.getHgRootFactory()); + myRemoteRepo = myTempFiles.createTempDir(); + copyRepository(new File("mercurial-tests/testData/rep2"), myRemoteRepo); + } + + @Test + public void simpleTest() throws IOException, VcsException { + TestLogger.enableMainAndVCSLoggerDebug(); + + VcsRoot root = vcsRoot().withUrl(myRemoteRepo).build(); + + + final List<CommitDataBean> commitInfos = mySupport.collectCommits(root, CheckoutRules.DEFAULT); + Assert.assertFalse(commitInfos.isEmpty()); + + for (CommitInfo commitInfo : commitInfos) { + System.out.println(commitInfo); + } + + final Set<String> branches = new TreeSet<String>(); + final Set<String> tags = new TreeSet<String>(); + final Set<String> commits = new TreeSet<String>(); + final Set<String> parents = new TreeSet<String>(); + for (CommitInfo commitInfo : commitInfos) { + branches.addAll(commitInfo.getBranches()); + tags.addAll(commitInfo.getTags()); + + //commit should be returned once + Assert.assertTrue(commits.add(commitInfo.getVersion())); + parents.addAll(commitInfo.getParentRevisions()); + } + + Assert.assertEquals(branches, new TreeSet<String>(Arrays.asList("default", "personal-branch", "test", "topic", "<TEST> Branch with exitics)(*&^%$#@!", "NULL"))); + Assert.assertEquals(tags, new TreeSet<String>(Arrays.asList("t1"))); + + //check all parent commits are included into the set + Assert.assertTrue(commits.containsAll(parents), "Unknown commits: " + new TreeSet<String>(parents){{removeAll(commits);}}); + + final String v = "4780519e01aa"; ///30 + Assert.assertFalse(parents.contains(v)); + } + + @Test + public void should_not_have_parse_errors() throws IOException, VcsException { + TestLogger.enableMainAndVCSLoggerDebug(); + + VcsRoot root = vcsRoot().withUrl(myRemoteRepo).build(); + + final List<CommitDataBean> commitInfos = mySupport.collectCommits(root, CheckoutRules.DEFAULT); + Assert.assertFalse(commitInfos.isEmpty()); + + for (CommitInfo commitInfo : commitInfos) { + System.out.println(commitInfo); + } + } + +}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/DagFeaturesTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/DagFeaturesTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -1,8 +1,5 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial; -import com.intellij.openapi.diagnostic.Logger; -import jetbrains.buildServer.TempFiles; -import jetbrains.buildServer.log.Log4jFactory; import jetbrains.buildServer.util.TestFor; import jetbrains.buildServer.vcs.CheckoutRules; import jetbrains.buildServer.vcs.ModificationData; @@ -22,18 +19,14 @@ * @author dmitry.neverov */ @Test -public class DagFeaturesTest { +public class DagFeaturesTest extends BaseMercurialTestCase { - static { - Logger.setFactory(new Log4jFactory()); - } - - private TempFiles myTempFiles = new TempFiles(); private MercurialVcsSupport myHg; private String myRepository; @BeforeMethod public void setUp() throws Exception { + super.setUp(); ServerPluginConfig config = new ServerPluginConfigBuilder() .cachesDir(myTempFiles.createTempDir()) .build(); @@ -45,10 +38,6 @@ myRepository = copy.getAbsolutePath(); } - public void tearDown() { - myTempFiles.cleanup(); - } - @TestFor(issues = "TW-17882") public void should_detect_changes_from_named_branches() throws Exception {
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgFileUtilTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgFileUtilTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -1,7 +1,6 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial; -import jetbrains.buildServer.util.FileUtil; import jetbrains.buildServer.util.TestFor; import org.testng.annotations.Test; @@ -12,7 +11,6 @@ import java.util.List; import java.util.Set; import java.util.concurrent.CountDownLatch; -import com.intellij.openapi.util.SystemInfo; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse;
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepoTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepoTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -4,13 +4,9 @@ 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; @@ -19,23 +15,7 @@ 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 class HgRepoTest extends BaseMercurialTestCase { public void subrepos() throws Exception { File repository = myTempFiles.createTempDir();
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgVcsRootFactoryTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgVcsRootFactoryTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -4,8 +4,6 @@ import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; import jetbrains.buildServer.util.TestFor; import jetbrains.buildServer.vcs.VcsRoot; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.io.File; @@ -16,19 +14,7 @@ import static org.testng.AssertJUnit.assertNull; @Test -public class HgVcsRootFactoryTest { - - private TempFiles myTempFiles; - - @BeforeMethod(alwaysRun = true) - public void setUp() { - myTempFiles = new TempFiles(); - } - - @AfterMethod(alwaysRun = true) - public void tearDown() { - myTempFiles.cleanup(); - } +public class HgVcsRootFactoryTest extends BaseMercurialTestCase { @TestFor(issues = "TW-25057") public void vcs_root_custom_clone_dir_should_not_contain_password() throws Exception {
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ListFilesSupportTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ListFilesSupportTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -1,8 +1,5 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial; -import com.intellij.openapi.diagnostic.Logger; -import jetbrains.buildServer.TempFiles; -import jetbrains.buildServer.log.Log4jFactory; import jetbrains.buildServer.util.TestFor; import jetbrains.buildServer.vcs.ListDirectChildrenPolicy; import jetbrains.buildServer.vcs.VcsException; @@ -27,25 +24,21 @@ * @author dmitry.neverov */ @Test -public class ListFilesSupportTest { - - static { - Logger.setFactory(new Log4jFactory()); - } +public class ListFilesSupportTest extends BaseMercurialTestCase { private MercurialVcsSupport myVcs; private VcsRoot myRoot; private File myRemoteRepoDir; @BeforeMethod - protected void setUp() throws Exception { - TempFiles tempFiles = new TempFiles(); + public void setUp() throws Exception { + super.setUp(); ServerPluginConfig myPluginConfig = new ServerPluginConfigBuilder() - .cachesDir(tempFiles.createTempDir()) + .cachesDir(myTempFiles.createTempDir()) .build(); myVcs = mercurialSupport().withConfig(myPluginConfig).build(); - myRemoteRepoDir = tempFiles.createTempDir(); + myRemoteRepoDir = myTempFiles.createTempDir(); copyRepository(new File("mercurial-tests/testData/rep1"), myRemoteRepoDir); myRoot = vcsRoot().withUrl(myRemoteRepoDir.getAbsolutePath()).build(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialModificationInfoBuilderTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,54 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import jetbrains.buildServer.vcs.CheckoutRules; +import jetbrains.buildServer.vcs.ModificationData; +import jetbrains.buildServer.vcs.RepositoryStateData; +import jetbrains.buildServer.vcs.VcsRoot; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.io.File; +import java.util.List; + +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialSupportBuilder.mercurialSupport; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.ModificationDataMatcher.modificationData; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.ServerPluginConfigBuilder.serverPluginConfig; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot; +import static jetbrains.buildServer.util.Util.map; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.testng.AssertJUnit.assertEquals; + +@RequiredHgVersion(min = "1.7.0") +@Test(dataProviderClass = HgVersionConstraint.class, dataProvider = "installedHgVersion") +public class MercurialModificationInfoBuilderTest extends BaseMercurialTestCase { + + private File myRemoteRepository; + private MercurialModificationInfoBuilder myModInfoBuilder; + + @BeforeMethod + public void setUp() throws Exception { + super.setUp(); + ServerPluginConfig config = serverPluginConfig() + .cachesDir(myTempFiles.createTempDir()) + .hgPath(Util.getHgPath()) + .build(); + + myRemoteRepository = myTempFiles.createTempDir(); + Util.copyRepository(new File("mercurial-tests/testData/rep2"), myRemoteRepository); + MercurialSupportBuilder hgBuilder = mercurialSupport().withConfig(config); + MercurialVcsSupport vcs = hgBuilder.build(); + myModInfoBuilder = new MercurialModificationInfoBuilder(vcs, hgBuilder.getHgRootFactory(), hgBuilder.getHgRepoFactory(), hgBuilder.getHgPathProvider()); + } + + + public void should_return_commits_for_every_revision_in_state(HgVersion _) throws Exception { + VcsRoot root = vcsRoot().withUrl(myRemoteRepository.getAbsolutePath()).build(); + RepositoryStateData state = RepositoryStateData.createVersionState("default", + map("default", "505c5b9d01e6", "personal-branch", "9ec402c74298")); + List<ModificationData> changes = myModInfoBuilder.fetchModificationInfo(root, state, CheckoutRules.DEFAULT); + assertThat(changes, hasItem(modificationData().withVersion("505c5b9d01e6"))); + assertThat(changes, hasItem(modificationData().withVersion("9ec402c74298"))); + assertEquals(2, changes.size()); + } +}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialSupportBuilder.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialSupportBuilder.java Tue Oct 01 12:52:11 2013 +0400 @@ -21,6 +21,7 @@ private List<MercurialServerExtension> myExtensions = new ArrayList<MercurialServerExtension>(); private HgVcsRootFactory myHgRootFactory; private RepoFactory myRepoFactory; + private ServerHgPathProvider myHgPathProvider; public static MercurialSupportBuilder mercurialSupport() { return new MercurialSupportBuilder(); @@ -33,16 +34,17 @@ EventDispatcher<ServerListener> dispatcher = EventDispatcher.create(ServerListener.class); myHgRootFactory = new HgVcsRootFactory(myConfig); MirrorManagerImpl mirrorManager = new MirrorManagerImpl(myConfig); - ServerHgPathProvider hgPathProvider = new ServerHgPathProvider(myConfig); - RepoFactory repoFactory = myRepoFactory != null ? myRepoFactory : new RepoFactory(myConfig, new TestCommandSettingsFactory()); - HgTestConnectionSupport testConnection = new HgTestConnectionSupport(myHgRootFactory, repoFactory, mirrorManager, hgPathProvider); + myHgPathProvider = new ServerHgPathProvider(myConfig); + if (myRepoFactory == null) + myRepoFactory = new RepoFactory(myConfig, new TestCommandSettingsFactory(), myHgPathProvider); + HgTestConnectionSupport testConnection = new HgTestConnectionSupport(myHgRootFactory, myRepoFactory, mirrorManager, myHgPathProvider); final ResetCacheRegister resetCacheManager = myContext.mock(ResetCacheRegister.class); myContext.checking(new Expectations() {{ allowing(resetCacheManager).registerHandler(with(any(ResetCacheHandler.class))); }}); - MercurialVcsSupport vcs = new MercurialVcsSupport(dispatcher, resetCacheManager, myConfig, hgPathProvider, - repoFactory, mirrorManager, myHgRootFactory, testConnection, new SubrepoCheckoutRulesProviderImpl()); - vcs.setExtensions(myExtensions); + MercurialVcsSupport vcs = new MercurialVcsSupport(dispatcher, resetCacheManager, myConfig, myHgPathProvider, + myRepoFactory, mirrorManager, myHgRootFactory, testConnection, new SubrepoCheckoutRulesProviderImpl()); + vcs.addExtensions(myExtensions); return vcs; } @@ -56,4 +58,16 @@ myRepoFactory = repoFactory; return this; } + + public HgVcsRootFactory getHgRootFactory() { + return myHgRootFactory; + } + + public RepoFactory getHgRepoFactory() { + return myRepoFactory; + } + + public ServerHgPathProvider getHgPathProvider() { + return myHgPathProvider; + } }
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -45,11 +45,12 @@ import static org.hamcrest.Matchers.not; @Test -public class MercurialVcsSupportTest extends BaseMercurialTestCase { +public class MercurialVcsSupportTest extends BaseMercurialPatchTestCase { private MercurialVcsSupport myVcs; private String myRep2Path = new File("mercurial-tests/testData/rep2").getAbsolutePath(); private ServerPluginConfig myPluginConfig; + private HgPathProvider myHgPathProvider; @BeforeMethod protected void setUp() throws Exception { @@ -57,7 +58,9 @@ myPluginConfig = new ServerPluginConfigBuilder() .cachesDir(myTempFiles.createTempDir()) .build(); - myVcs = mercurialSupport().withConfig(myPluginConfig).build(); + MercurialSupportBuilder mercurialBuilder = mercurialSupport().withConfig(myPluginConfig); + myVcs = mercurialBuilder.build(); + myHgPathProvider = mercurialBuilder.getHgPathProvider(); } protected String getTestDataPath() { @@ -548,7 +551,7 @@ if (!SystemInfo.isUnix) return; - RepoFactory repoFactory = new RepoFactory(myPluginConfig, new TestCommandSettingsFactory()); + RepoFactory repoFactory = new RepoFactory(myPluginConfig, new TestCommandSettingsFactory(), myHgPathProvider); //create a file on the server File dirOnTheServer = myTempFiles.createTempDir();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MergeSupportSubreposTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,68 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import jetbrains.buildServer.vcs.*; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.io.File; +import java.util.List; + +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialSupportBuilder.mercurialSupport; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.ModificationDataMatcher.modificationData; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.Util.copyRepository; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.testng.AssertJUnit.assertFalse; + +@Test +public class MergeSupportSubreposTest extends BaseMercurialTestCase { + + private File mySubrepo1; + private File mySubrepo2; + private MercurialVcsSupport myVcs; + private MercurialMergeSupport myMergeSupport; + + @BeforeMethod + @Override + public void setUp() throws Exception { + super.setUp(); + File parentDir = myTempFiles.createTempDir(); + mySubrepo1 = new File(parentDir, "subrepo1"); + mySubrepo2 = new File(parentDir, "subrepo2"); + mySubrepo1.mkdirs(); + mySubrepo2.mkdirs(); + copyRepository(new File("mercurial-tests/testData/merge/subrepos/subrepo1"), mySubrepo1); + copyRepository(new File("mercurial-tests/testData/merge/subrepos/subrepo2"), mySubrepo2); + + ServerPluginConfig pluginConfig = new ServerPluginConfigBuilder() + .cachesDir(myTempFiles.createTempDir()) + .build(); + MercurialSupportBuilder mercurialBuilder = mercurialSupport().withConfig(pluginConfig); + myVcs = mercurialBuilder.build(); + myMergeSupport = new MercurialMergeSupport(myVcs, myVcs.getMirrorManager(), pluginConfig, + mercurialBuilder.getHgRootFactory(), mercurialBuilder.getHgRepoFactory()); + } + + + public void should_do_merge_in_subrepo_if_it_has_appropriate_branch() throws Exception { + VcsRoot root = vcsRoot().withUrl(mySubrepo1).withSubrepoChanges(true).build(); + RepositoryStateData beforeMerge = myVcs.getCollectChangesPolicy().getCurrentState(root); + myMergeSupport.merge(root, "0bd1ae88632d", "default", "merge into default", new MergeOptions()); + RepositoryStateData afterMerge = myVcs.getCollectChangesPolicy().getCurrentState(root); + List<ModificationData> ms = myVcs.getCollectChangesPolicy().collectChanges(root, beforeMerge, afterMerge, CheckoutRules.DEFAULT); + assertThat("Cannot find main repo merge commit", ms, hasItem(modificationData().withDescription("merge into default") + .withParentRevisions("eb211547efbe", "0bd1ae88632d"))); + assertThat("Cannot find subrepo merge commit", ms, hasItem(modificationData().withDescription("merge into default") + .withParentRevisions("675fa105b184", "1532dee5d922"))); + } + + + public void should_report_conflicts_from_subrepos() throws Exception { + VcsRoot root = vcsRoot().withUrl(mySubrepo1).withSubrepoChanges(true).build(); + MergeResult result = myMergeSupport.merge(root, "3e43f76179ed", "default", "merge into default", new MergeOptions()); + assertFalse(result.isSuccess()); + assertThat("conflict from main repo is not reported", result.getConflicts(), hasItem("b/c")); + assertThat("conflict from subrepo is not reported", result.getConflicts(), hasItem("subrepo2/b/c")); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MergeSupportTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,115 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import jetbrains.buildServer.vcs.*; +import org.jetbrains.annotations.NotNull; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.io.File; +import java.util.List; +import java.util.Map; + +import static java.util.Arrays.asList; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialSupportBuilder.mercurialSupport; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.ModificationDataMatcher.modificationData; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.Util.copyRepository; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertTrue; + + +@RequiredHgVersion(min = "1.7.0") +@Test(dataProviderClass = HgVersionConstraint.class, dataProvider = "installedHgVersion") +public class MergeSupportTest extends BaseMercurialTestCase { + + private File myRemoteRepo; + private MercurialVcsSupport myVcs; + private MercurialMergeSupport myMergeSupport; + + @Override + @BeforeMethod + public void setUp() throws Exception { + super.setUp(); + ServerPluginConfig pluginConfig = new ServerPluginConfigBuilder() + .cachesDir(myTempFiles.createTempDir()) + .build(); + MercurialSupportBuilder mercurialBuilder = mercurialSupport().withConfig(pluginConfig); + myVcs = mercurialBuilder.build(); + myMergeSupport = new MercurialMergeSupport(myVcs, myVcs.getMirrorManager(), pluginConfig, mercurialBuilder.getHgRootFactory(), mercurialBuilder.getHgRepoFactory()); + myRemoteRepo = myTempFiles.createTempDir(); + copyRepository(new File("mercurial-tests/testData/merge/no.subrepos"), myRemoteRepo); + } + + + public void should_return_succesful_result_when_merge_succeeds(@NotNull HgVersion _) throws Exception { + VcsRoot root = vcsRoot().withUrl(myRemoteRepo).build(); + MergeResult mergeResult = myMergeSupport.merge(root, "2742914d19b2", "default", "merge topic1 into default", new MergeOptions()); + assertTrue(mergeResult.isSuccess()); + } + + + public void result_of_succesful_merge_should_appear_in_remote_repository(@NotNull HgVersion _) throws Exception { + final String mergeDestinationBranch = "default"; + final String mergeCommitMessage = "merge topic1 into default"; + + VcsRoot root = vcsRoot().withUrl(myRemoteRepo).build(); + RepositoryStateData stateBeforeMerge = myVcs.getCollectChangesPolicy().getCurrentState(root); + String dstBranchRevBefore = stateBeforeMerge.getBranchRevisions().get(mergeDestinationBranch); + + myMergeSupport.merge(root, "2742914d19b2", mergeDestinationBranch, mergeCommitMessage, new MergeOptions()); + RepositoryStateData stateAfterMerge = myVcs.getCollectChangesPolicy().getCurrentState(root); + String dstBranchRevAfter = stateAfterMerge.getBranchRevisions().get(mergeDestinationBranch); + + assertFalse("Revision of the destination branch is not changed", dstBranchRevAfter.equals(dstBranchRevBefore)); + + List<ModificationData> changes = myVcs.getCollectChangesPolicy().collectChanges(root, stateBeforeMerge, stateAfterMerge, CheckoutRules.DEFAULT); + assertThat(changes, hasItem(modificationData().withDescription(mergeCommitMessage))); + } + + + public void should_return_unsuccesful_result_when_merge_fails(@NotNull HgVersion _) throws Exception { + VcsRoot root = vcsRoot().withUrl(myRemoteRepo).build(); + MergeResult mergeResult = myMergeSupport.merge(root, "79d836707416", "default", "merge topic2 into default", new MergeOptions()); + assertFalse(mergeResult.isSuccess()); + assertThat(mergeResult.getConflicts(), hasItem("b/c")); + } + + + public void result_of_failed_merge_should_not_appear_in_remote_repository(@NotNull HgVersion _) throws Exception { + final String mergeDestinationBranch = "default"; + + VcsRoot root = vcsRoot().withUrl(myRemoteRepo).build(); + RepositoryStateData stateBeforeMerge = myVcs.getCollectChangesPolicy().getCurrentState(root); + String dstBranchRevBefore = stateBeforeMerge.getBranchRevisions().get(mergeDestinationBranch); + + myMergeSupport.merge(root, "79d836707416", mergeDestinationBranch, "merge topic2 into default", new MergeOptions()); + RepositoryStateData stateAfterMerge = myVcs.getCollectChangesPolicy().getCurrentState(root); + String dstBranchRevAfter = stateAfterMerge.getBranchRevisions().get(mergeDestinationBranch); + + assertTrue("Revision of the destination branch changed after failed merge", dstBranchRevAfter.equals(dstBranchRevBefore)); + } + + + public void try_merge_returns_correct_result_for_every_task(@NotNull HgVersion _) throws Exception { + VcsRoot root = vcsRoot().withUrl(myRemoteRepo).build(); + + final MergeTask topic1ToDefault = new MergeTask("2742914d19b2", "09dd527b77ec"); + final MergeTask topic2ToDefault = new MergeTask("79d836707416", "09dd527b77ec"); + final MergeTask topic1ToTopic2 = new MergeTask("2742914d19b2", "79d836707416"); + Map<MergeTask, MergeResult> results = myMergeSupport.tryMerge(root, asList(topic1ToDefault, topic2ToDefault, topic1ToTopic2), new MergeOptions()); + + assertTrue(results.get(topic1ToDefault).isSuccess()); + assertFalse(results.get(topic2ToDefault).isSuccess()); + assertThat(results.get(topic2ToDefault).getConflicts(), hasItem("b/c")); + assertTrue(results.get(topic1ToTopic2).isSuccess()); + } + + + public void merge_into_same_branch(@NotNull HgVersion _) throws Exception { + VcsRoot root = vcsRoot().withUrl(myRemoteRepo).build(); + MergeResult result = myMergeSupport.merge(root, "6370ce18689a", "default", "merge into same branch", new MergeOptions()); + assertTrue(result.isSuccess()); + } +}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MirrorManagerTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MirrorManagerTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -1,10 +1,7 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial; -import jetbrains.buildServer.TempFiles; import jetbrains.buildServer.util.Hash; -import junit.framework.TestCase; import org.jetbrains.annotations.NotNull; -import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -12,20 +9,23 @@ import java.io.IOException; import java.util.List; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertTrue; + /** * @author dmitry.neverov */ @Test -public class MirrorManagerTest extends TestCase { +public class MirrorManagerTest extends BaseMercurialTestCase { - private TempFiles myTempFiles; private File myRootDir; private MirrorManagerImpl myManager; @BeforeMethod public void setUp() throws Exception { - myTempFiles = new TempFiles(); + super.setUp(); myRootDir = myTempFiles.createTempDir(); myManager = new MirrorManagerImpl(new PluginConfig() { @NotNull @@ -35,11 +35,6 @@ }); } - @AfterMethod - public void tearDown() { - myTempFiles.cleanup(); - } - public void manager_should_create_an_empty_map_file() { assertTrue(myRootDir.listFiles().length == 1);
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ModificationDataMatcher.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ModificationDataMatcher.java Tue Oct 01 12:52:11 2013 +0400 @@ -6,22 +6,31 @@ import org.jetbrains.annotations.NotNull; import java.util.HashMap; +import java.util.List; import java.util.Map; +import static java.util.Arrays.asList; + public class ModificationDataMatcher extends TypeSafeMatcher<ModificationData> { private String myVersion; + private String myDescription; private Map<String, String> myVcsRootProperties = new HashMap<String, String>(); private Map<String, String> myAttributes = new HashMap<String, String>(); + private List<String> myParentRevisions; @Override public boolean matchesSafely(ModificationData m) { if (myVersion != null && !myVersion.equals(m.getDisplayVersion())) return false; + if (myDescription != null && !myDescription.equals(m.getDescription())) + return false; if (!myVcsRootProperties.isEmpty() && !myVcsRootProperties.equals(m.getVcsRootObject().getProperties())) return false; if (!myAttributes.isEmpty() && !containsAllAttributes(m.getAttributes())) return false; + if (myParentRevisions != null && !m.getParentRevisions().equals(myParentRevisions)) + return false; return true; } @@ -29,10 +38,14 @@ description.appendText("modification"); if (myVersion != null) description.appendText(" with version ").appendValue(myVersion); + if (myDescription != null) + description.appendText(" with description ").appendValue(myDescription); if (!myVcsRootProperties.isEmpty()) description.appendText(" with vcs root properties ").appendValue(myVcsRootProperties); if (!myAttributes.isEmpty()) description.appendText(" with attributes ").appendValue(myAttributes); + if (myParentRevisions != null) + description.appendText(" with parent revisions ").appendValue(myParentRevisions); } public static ModificationDataMatcher modificationData() { @@ -44,6 +57,11 @@ return this; } + public ModificationDataMatcher withDescription(@NotNull String description) { + myDescription = description; + return this; + } + public ModificationDataMatcher withVcsRootProperties(@NotNull Map<String, String> properties) { myVcsRootProperties.putAll(properties); return this; @@ -54,6 +72,11 @@ return this; } + public ModificationDataMatcher withParentRevisions(String... parentRevisions) { + myParentRevisions = asList(parentRevisions); + return this; + } + private boolean containsAllAttributes(@NotNull Map<String, String> attributes) { for (Map.Entry<String, String> e : myAttributes.entrySet()) { String expectedValue = e.getValue();
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/RevisionFormatTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/RevisionFormatTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -1,14 +1,9 @@ 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 jetbrains.buildServer.vcs.*; -import jetbrains.buildServer.vcs.patches.PatchTestCase; import org.jetbrains.annotations.NotNull; -import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -24,20 +19,15 @@ import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot; @Test -public class RevisionFormatTest extends PatchTestCase { +public class RevisionFormatTest extends BaseMercurialPatchTestCase { - static { - Logger.setFactory(new Log4jFactory()); - } - - private TempFiles myTempFiles; private MercurialVcsSupport myVcs; private VcsRoot myRoot; private File myRemoteRepoDir; @BeforeMethod public void setUp() throws Exception { - myTempFiles = new TempFiles(); + super.setUp(); ServerPluginConfig pluginConfig = new ServerPluginConfigBuilder() .cachesDir(myTempFiles.createTempDir()) .build(); @@ -47,11 +37,6 @@ myRoot = vcsRoot().withUrl(myRemoteRepoDir.getAbsolutePath()).build(); } - @AfterMethod - public void tearDown() { - myTempFiles.cleanup(); - } - public void collect_changes_result_does_not_depend_on_revnums() throws VcsException { List<ModificationData> changesWithRevnums = myVcs.getCollectChangesPolicy().collectChanges(myRoot,
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigBuilder.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigBuilder.java Tue Oct 01 12:52:11 2013 +0400 @@ -15,8 +15,9 @@ private String myHgPath; private File myCachesDir; private boolean myDontUseRevsets = false; - private boolean myDetectSubrepoChanges = false; + private boolean myDetectSubrepoChanges = true; private long myMirrorExpirationTimeout; + private boolean myTagsAsBranches = true; @NotNull public ServerPluginConfig build() { @@ -53,6 +54,10 @@ return true; } + public boolean useTagsAsBranches() { + return myTagsAsBranches; + } + public int getMaxDagNodesCount() { return 0; } @@ -114,4 +119,9 @@ myMirrorExpirationTimeout = timeoutMillis; return this; } + + public ServerPluginConfigBuilder withTagsAsBranches(boolean tagsAsBranches) { + myTagsAsBranches = tagsAsBranches; + return this; + } }
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SubrepoChangesTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SubrepoChangesTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -1,20 +1,15 @@ 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.CatCommand; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.CommandSettingsFactory; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.TestCommandSettingsFactory; -import jetbrains.buildServer.log.Log4jFactory; import jetbrains.buildServer.vcs.*; import org.jetbrains.annotations.NotNull; -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.HashMap; import java.util.List; import java.util.Map; @@ -30,22 +25,18 @@ @RequiredHgVersion(min = "1.7.0") //support subrepos only for hg with revsets @Test(dataProviderClass = HgVersionConstraint.class, dataProvider = "installedHgVersion") -public class SubrepoChangesTest { +public class SubrepoChangesTest extends BaseMercurialTestCase { - static { - Logger.setFactory(new Log4jFactory()); - } - - private TempFiles myTempFiles; private MercurialVcsSupport myVcs; private File myRemoteRepo1; private File myRemoteRepo2; private File myRemoteRepo3; private File myRepoNoSubs; + private HgPathProvider myHgPathProvider; @BeforeMethod - public void setUp() throws IOException { - myTempFiles = new TempFiles(); + public void setUp() throws Exception { + super.setUp(); ServerPluginConfig pluginConfig = new ServerPluginConfigBuilder() .cachesDir(myTempFiles.createTempDir()) .detectSubrepoChanges(true) @@ -59,12 +50,9 @@ copyRepository(new File("mercurial-tests/testData/subrepos/r2"), myRemoteRepo2); copyRepository(new File("mercurial-tests/testData/subrepos/r3"), myRemoteRepo3); copyRepository(new File("mercurial-tests/testData/rep1"), myRepoNoSubs); - myVcs = mercurialSupport().withConfig(pluginConfig).build(); - } - - @AfterMethod - public void tearDown() { - myTempFiles.cleanup(); + MercurialSupportBuilder mercurialBuilder = mercurialSupport().withConfig(pluginConfig); + myVcs = mercurialBuilder.build(); + myHgPathProvider = mercurialBuilder.getHgPathProvider(); } @@ -226,7 +214,7 @@ .build(); final AtomicInteger catCallCounter = new AtomicInteger(0); - RepoFactory repoFactory = new RepoFactory(pluginConfig, new TestCommandSettingsFactory()) { + RepoFactory repoFactory = new RepoFactory(pluginConfig, new TestCommandSettingsFactory(), myHgPathProvider) { @NotNull @Override public ServerHgRepo create(@NotNull File workingDir, @NotNull String hgPath, @NotNull AuthSettings authSettings) throws VcsException {
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SubrepoPatchTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/SubrepoPatchTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -1,10 +1,7 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial; -import com.intellij.openapi.diagnostic.Logger; -import jetbrains.buildServer.log.Log4jFactory; import jetbrains.buildServer.vcs.CheckoutRules; import jetbrains.buildServer.vcs.VcsRoot; -import jetbrains.buildServer.vcs.impl.VcsRootImpl; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -17,11 +14,7 @@ import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot; @Test -public class SubrepoPatchTest extends BaseMercurialTestCase { - - static { - Logger.setFactory(new Log4jFactory()); - } +public class SubrepoPatchTest extends BaseMercurialPatchTestCase { private MercurialVcsSupport myVcs; private File myRemoteRepo1;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/TagsTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,74 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import jetbrains.buildServer.vcs.RepositoryStateData; +import jetbrains.buildServer.vcs.VcsRoot; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.IOException; + +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.BookmarksTest.RepositoryStateDataMatcher.hasBranch; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.BookmarksTest.RepositoryStateDataMatcher.hasNoBranch; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialSupportBuilder.mercurialSupport; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.ServerPluginConfigBuilder.serverPluginConfig; +import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.not; + +@RequiredHgVersion(min = "1.7.0") +@Test(dataProviderClass = HgVersionConstraint.class, dataProvider = "installedHgVersion") +public class TagsTest extends BaseMercurialTestCase { + + private File myRemoteRepository; + private ServerPluginConfigBuilder myConfig; + + @BeforeMethod + public void setUp() throws Exception { + super.setUp(); + myConfig = serverPluginConfig() + .cachesDir(myTempFiles.createTempDir()) + .hgPath(Util.getHgPath()); + + myRemoteRepository = myTempFiles.createTempDir(); + Util.copyRepository(new File("mercurial-tests/testData/tags"), myRemoteRepository); + } + + public void no_tags_reported_by_default(HgVersion _) throws Exception { + VcsRoot root = vcsRoot().withUrl(myRemoteRepository.getAbsolutePath()).build(); + RepositoryStateData state = getVcs().getCollectChangesPolicy().getCurrentState(root); + assertThat(state, not(hasBranch("v1").withRevision("fa7ad5b80a88"))); + assertThat(state, not(hasBranch("v4").withRevision("f7fbcc489e40"))); + } + + public void should_report_tag_revisions(HgVersion _) throws Exception { + VcsRoot root = vcsRoot().withUrl(myRemoteRepository.getAbsolutePath()).withTagsEnabled(true).build(); + RepositoryStateData state = getVcs().getCollectChangesPolicy().getCurrentState(root); + assertThat(state, hasBranch("v1").withRevision("fa7ad5b80a88")); + assertThat(state, hasBranch("v4").withRevision("f7fbcc489e40")); + } + + public void branch_has_higher_precedence_over_tag(HgVersion _) throws Exception { + VcsRoot root = vcsRoot().withUrl(myRemoteRepository.getAbsolutePath()).withTagsEnabled(true).build(); + RepositoryStateData state = getVcs().getCollectChangesPolicy().getCurrentState(root); + assertThat(state, hasBranch("topic").withRevision("efde33cd0b66")); + } + + public void tags_can_be_turned_off_globally(HgVersion _) throws Exception { + myConfig.withTagsAsBranches(false); + VcsRoot root = vcsRoot().withUrl(myRemoteRepository.getAbsolutePath()).withTagsEnabled(true).build(); + RepositoryStateData state = getVcs().getCollectChangesPolicy().getCurrentState(root); + assertThat(state, not(hasBranch("v1").withRevision("fa7ad5b80a88"))); + assertThat(state, not(hasBranch("v4").withRevision("f7fbcc489e40"))); + } + + public void tags_should_not_include_tip(HgVersion _) throws Exception { + VcsRoot root = vcsRoot().withUrl(myRemoteRepository.getAbsolutePath()).withTagsEnabled(true).build(); + RepositoryStateData state = getVcs().getCollectChangesPolicy().getCurrentState(root); + assertThat(state, hasNoBranch("tip")); + } + + private MercurialVcsSupport getVcs() throws IOException { + return mercurialSupport().withConfig(myConfig.build()).build(); + } +}
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/UnrelatedResitoriesTest.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/UnrelatedResitoriesTest.java Tue Oct 01 12:52:11 2013 +0400 @@ -1,14 +1,10 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial; -import com.intellij.openapi.diagnostic.Logger; -import jetbrains.buildServer.TempFiles; -import jetbrains.buildServer.log.Log4jFactory; import jetbrains.buildServer.util.FileUtil; import jetbrains.buildServer.vcs.CheckoutRules; import jetbrains.buildServer.vcs.VcsException; import jetbrains.buildServer.vcs.impl.VcsRootImpl; import org.jetbrains.annotations.NotNull; -import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -23,22 +19,17 @@ * @author dmitry.neverov */ @Test -public class UnrelatedResitoriesTest { +public class UnrelatedResitoriesTest extends BaseMercurialTestCase { private final static String CURRENT_VERSION_OF_NEW_REPO = "4780519e01aa"; private MercurialVcsSupport myVcs; - private TempFiles myTempFiles; private File myRepositoryLocation; private VcsRootImpl myRoot; private ServerPluginConfig myPluginConfig; - static { - Logger.setFactory(new Log4jFactory()); - } - @BeforeMethod public void setUp() throws Exception { - myTempFiles = new TempFiles(); + super.setUp(); myPluginConfig = new ServerPluginConfigBuilder() .cachesDir(myTempFiles.createTempDir()) .build(); @@ -48,11 +39,6 @@ myRoot = new VcsRootBuilder().withUrl(myRepositoryLocation.getCanonicalPath()).build(); } - @AfterMethod - public void tearDown() { - myTempFiles.cleanup(); - } - public void should_be_able_to_sync_when_repository_became_unrelated() throws Exception { myVcs = createVcs();
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/VcsRootBuilder.java Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/VcsRootBuilder.java Tue Oct 01 12:52:11 2013 +0400 @@ -1,13 +1,14 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial; -import java.io.File; -import java.io.IOException; import jetbrains.buildServer.vcs.SVcsRoot; import jetbrains.buildServer.vcs.impl.VcsRootImpl; import org.jetbrains.annotations.NotNull; import org.jmock.Expectations; import org.jmock.Mockery; +import java.io.File; +import java.io.IOException; + /** * @author dmitry.neverov */ @@ -23,6 +24,7 @@ private boolean myUncompressed = true; private File myCloneRepositoryTo; private boolean myDetectSubrepoChanges = false; + private boolean myTagsAsBranches = false; public static VcsRootBuilder vcsRoot() { return new VcsRootBuilder(); @@ -40,6 +42,7 @@ vcsRoot.addProperty(Constants.DETECT_SUBREPO_CHANGES, String.valueOf(myDetectSubrepoChanges)); if (myCloneRepositoryTo != null) vcsRoot.addProperty(Constants.SERVER_CLONE_PATH_PROP, String.valueOf(myCloneRepositoryTo.getAbsolutePath())); + vcsRoot.addProperty(Constants.USE_TAGS_AS_BRANCHES, String.valueOf(myTagsAsBranches)); return vcsRoot; } @@ -58,6 +61,7 @@ allowing(root).getProperty(with(Constants.UNCOMPRESSED_TRANSFER)); will(returnValue(null)); allowing(root).getProperty(with(Constants.USER_FOR_TAG)); will(returnValue(myUserForTag)); allowing(root).getProperty(with(Constants.DETECT_SUBREPO_CHANGES)); will(returnValue(String.valueOf(myDetectSubrepoChanges))); + allowing(root).getProperty(with(Constants.USE_TAGS_AS_BRANCHES)); will(returnValue(String.valueOf(myTagsAsBranches))); }}); if (myCloneRepositoryTo != null) { context.checking(new Expectations() {{ @@ -74,6 +78,12 @@ } + public VcsRootBuilder withUrl(@NotNull File repository) { + myRepository = repository.getAbsolutePath(); + return this; + } + + public VcsRootBuilder withUserName(@NotNull String username) { myUsername = username; return this; @@ -120,4 +130,10 @@ myDetectSubrepoChanges = detectSubrepoChanges; return this; } + + + public VcsRootBuilder withTagsEnabled(boolean useTagsAsBranches) { + myTagsAsBranches = useTagsAsBranches; + return this; + } }
--- a/mercurial-tests/src/testng.xml Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/src/testng.xml Tue Oct 01 12:52:11 2013 +0400 @@ -32,6 +32,10 @@ <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialXmlLogParserTest"/> <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.HgVcsRootFactoryTest"/> <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.SubRepoTest"/> + <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.MergeSupportTest"/> + <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.TagsTest"/> + <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.CommitsInfoBuilderSupportTest"/> + <class name="jetbrains.buildServer.buildTriggers.vcs.mercurial.MercurialModificationInfoBuilderTest"/> </classes> </test> </suite>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/README Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,45 @@ +no.subrepos + +o 4:79d836707416 topic2 +| +| o 3:2742914d19b2 topic1 +|/ +| o 2:09dd527b77ec +|/ +o 1:6370ce18689a +| +o 0:7e3988f0f412 + + + +subrepo1 + +o 6:eb211547efbe ~> subrepo2 675fa105b184 +| +| o 5:a3db56ba38d3 topic3 ~> subrepo2 085a6376bbce +| | +| | o 4:3e43f76179ed topic2 ~> subrepo2 085a6376bbce +| |/ +| | o 3:0bd1ae88632d topic1 ~> subrepo2 1532dee5d922 +| |/ +o | 2:111ee5cb00c8 ~> subrepo2 627ca21f914a +|/ +o 1:a4bb39f3d42b ~> subrepo2 627ca21f914a +| +o 0:f43f3725e922 + + +subrepo2 + +o 4:085a6376bbce topic2 +| +| o 3:1532dee5d922 topic1 +|/ +| o 2:675fa105b184 +|/ +o 1:627ca21f914a +| +o 0:5a88c102487e + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/no.subrepos/hg/branch Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +topic2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/no.subrepos/hg/cache/branchheads-served Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,4 @@ +79d8367074167bba5a1820ad757f4052b5777d20 4 +09dd527b77ec6e1ab9396bc16eb3b5cd09c55d11 default +2742914d19b233227f753c51110959b407eeff6e topic1 +79d8367074167bba5a1820ad757f4052b5777d20 topic2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/no.subrepos/hg/cache/tags Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,3 @@ +3 2742914d19b233227f753c51110959b407eeff6e +2 09dd527b77ec6e1ab9396bc16eb3b5cd09c55d11 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/no.subrepos/hg/last-message.txt Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +create b/c conflicting with default \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/no.subrepos/hg/requires Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,4 @@ +dotencode +fncache +revlogv1 +store
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/no.subrepos/hg/store/fncache Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,3 @@ +data/b/c.i +data/b/d.i +data/a.i
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/no.subrepos/hg/store/phaseroots Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +1 7e3988f0f412b846df355cb77cf5b863dd42fb5f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/no.subrepos/hg/store/undo.phaseroots Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +1 7e3988f0f412b846df355cb77cf5b863dd42fb5f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/no.subrepos/hg/undo.branch Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +topic2 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/no.subrepos/hg/undo.desc Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,2 @@ +4 +commit
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo1/hg/branch Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +default
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo1/hg/cache/branchheads-served Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,5 @@ +eb211547efbe93ab842d97263d645fcf77c01b8e 6 +eb211547efbe93ab842d97263d645fcf77c01b8e default +0bd1ae88632d2694bdb227b76c4e7f7346bd1718 topic1 +3e43f76179edacde228056f906d16bdbd8b3ba30 topic2 +a3db56ba38d345e814abca5a0555243b4db809fd topic3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo1/hg/cache/tags Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,5 @@ +5 a3db56ba38d345e814abca5a0555243b4db809fd +4 3e43f76179edacde228056f906d16bdbd8b3ba30 +3 0bd1ae88632d2694bdb227b76c4e7f7346bd1718 +2 111ee5cb00c83258c9fd13e402e20741bb575510 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo1/hg/last-message.txt Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +track last subrepo1 commit in default \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo1/hg/requires Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,4 @@ +dotencode +fncache +revlogv1 +store
Binary file mercurial-tests/testData/merge/subrepos/subrepo1/hg/store/data/~2ehgsubstate.i has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo1/hg/store/fncache Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,5 @@ +data/b/c.i +data/.hgsubstate.i +data/b/d.i +data/.hgsub.i +data/a.i
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo1/hg/store/phaseroots Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +1 f43f3725e92209f5e82118524ac8075a62326151
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo1/hg/store/undo.phaseroots Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +1 f43f3725e92209f5e82118524ac8075a62326151
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo1/hg/undo.branch Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +default \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo1/hg/undo.desc Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,2 @@ +6 +commit
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo2/hg/branch Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +topic2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo2/hg/cache/branchheads-served Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,4 @@ +085a6376bbceaefcdaa2c9c7a8ae3ea9ec91d2c3 4 +675fa105b184f695b11cbf31d08cda09f1114cc2 default +1532dee5d922539bb47ae13c3d1eadd126dad426 topic1 +085a6376bbceaefcdaa2c9c7a8ae3ea9ec91d2c3 topic2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo2/hg/cache/tags Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,4 @@ +4 085a6376bbceaefcdaa2c9c7a8ae3ea9ec91d2c3 +3 1532dee5d922539bb47ae13c3d1eadd126dad426 +2 675fa105b184f695b11cbf31d08cda09f1114cc2 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo2/hg/last-message.txt Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +create b/c conflicting with default \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo2/hg/requires Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,4 @@ +dotencode +fncache +revlogv1 +store
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo2/hg/store/fncache Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,3 @@ +data/b/c.i +data/b/d.i +data/a.i
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo2/hg/store/phaseroots Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +1 5a88c102487e07f4413e3574357303a38e483ac0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo2/hg/store/undo.phaseroots Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +1 5a88c102487e07f4413e3574357303a38e483ac0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo2/hg/undo.branch Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +topic2 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/merge/subrepos/subrepo2/hg/undo.desc Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,2 @@ +4 +commit
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/rep2/hg/store/phaseroots Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +1 ef4a538a17cf3e72eeffcc59140805a69e8c9b03
--- a/mercurial-tests/testData/rep2/hg/undo.branch Tue Oct 01 12:51:13 2013 +0400 +++ b/mercurial-tests/testData/rep2/hg/undo.branch Tue Oct 01 12:52:11 2013 +0400 @@ -1,1 +1,1 @@ -default \ No newline at end of file +<TEST> Branch with exitics)(*&^%$#@! \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/rep2/hg/undo.desc Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,2 @@ +32 +commit
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/tags/README Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,19 @@ + o 9:72902de1ba45 +tag topic -> 3256c19d708b + | +o | 8:efde33cd0b66 (topic) +tag v1 -> fa7ad5b80a88 +| | +| o | 7:210d711041da (topic2) +tag v1 -> b86ee8b83781 +| | | +| o | 6:b86ee8b83781 (topic2) +| | | +| | o 5:3256c19d708b +tag v4 -> f7fbcc489e40 +| | | +| | o 4:f7fbcc489e40 +| |/ +o | 3:fa7ad5b80a88 (topic) +tag v1 -> 6c3929c66c32 +| | +o | 2:6c3929c66c32 (topic) +|/ +o 1:b6e596caff9d +tag v1 -> 1ecfad722425 +| +o 0:1ecfad722425
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/tags/hg/branch Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +default
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/tags/hg/cache/branchheads-served Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,4 @@ +72902de1ba4503a2acabdac782dd1baedc56c590 9 +72902de1ba4503a2acabdac782dd1baedc56c590 default +efde33cd0b66ae0fb22031ae49890ed8291d54b0 topic +210d711041da69982df2472bdbae12d3da50b7eb topic2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/tags/hg/cache/tags Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,11 @@ +9 72902de1ba4503a2acabdac782dd1baedc56c590 e2013c4534f7af87eba501437ab756184ce06738 +8 efde33cd0b66ae0fb22031ae49890ed8291d54b0 16b0ff5750dd8451acd25496c85e8ee8827f02c8 +7 210d711041da69982df2472bdbae12d3da50b7eb 9b2a39cbdbc150021d3769e20b8f75affa52af84 + +3256c19d708b4efae92b281b386876eab63d4b7e topic +1ecfad72242555475feeefe00643a834cae04b15 v1 +1ecfad72242555475feeefe00643a834cae04b15 v1 +6c3929c66c328e85039f7588fc9344f93e0bd04b v1 +b86ee8b83781935bca1c5ee4ffe7f3b6f12923f2 v1 +fa7ad5b80a88c64f8f32d1b7a0cc96fb2a5092ae v1 +f7fbcc489e403a950ddba6e4a7b1674b60d66c65 v4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/tags/hg/last-message.txt Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +Added tag topic for changeset 3256c19d708b \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/tags/hg/requires Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,4 @@ +dotencode +fncache +revlogv1 +store
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/tags/hg/store/fncache Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,2 @@ +data/.hgtags.i +data/a.i
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/tags/hg/store/phaseroots Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +1 1ecfad72242555475feeefe00643a834cae04b15
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/tags/hg/store/undo.phaseroots Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +1 1ecfad72242555475feeefe00643a834cae04b15
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/tags/hg/undo.branch Tue Oct 01 12:52:11 2013 +0400 @@ -0,0 +1,1 @@ +default \ No newline at end of file