Mercurial > hg > mercurial
changeset 631:d28d52336ce5
Implement MergeSupport
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java Thu Aug 01 17:36:57 2013 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgRepo.java Wed Aug 07 13:08:31 2013 +0400 @@ -97,6 +97,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(); }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResult.java Thu Aug 01 17:36:57 2013 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResult.java Wed Aug 07 13:08:31 2013 +0400 @@ -54,6 +54,10 @@ mySettings = settings; } + public int getExitCode() { + return myDelegate.getExitCode(); + } + @NotNull public String getStdout() { return removePrivateData(myDelegate.getStdout(), myPrivateData);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommitCommand.java Wed Aug 07 13:08:31 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; + +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"); + if (myCommitMessage != null) + cmd.addParameters("-m", myCommitMessage); + runCommand(cmd); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/MergeCommand.java Wed Aug 07 13:08:31 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 Wed Aug 07 13:08:31 2013 +0400 @@ -0,0 +1,29 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial.command; + +import jetbrains.buildServer.vcs.VcsException; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class 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(); + 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/exception/MergeConflictException.java Wed Aug 07 13:08:31 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"); + } +}
--- a/mercurial-server-tc/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialExtensionRegistry.java Thu Aug 01 17:36:57 2013 +0400 +++ b/mercurial-server-tc/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialExtensionRegistry.java Wed Aug 07 13:08:31 2013 +0400 @@ -8,6 +8,6 @@ public MercurialExtensionRegistry(@NotNull MercurialVcsSupport vcs, @NotNull Collection<MercurialServerExtension> extensions) { - vcs.setExtensions(extensions); + vcs.addExtensions(extensions); } }
--- a/mercurial-server/src/META-INF/build-server-plugin-mercurial.xml Thu Aug 01 17:36:57 2013 +0400 +++ b/mercurial-server/src/META-INF/build-server-plugin-mercurial.xml Wed Aug 07 13:08:31 2013 +0400 @@ -11,4 +11,5 @@ <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"/> </beans>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialMergeSupport.java Wed Aug 07 13:08:31 2013 +0400 @@ -0,0 +1,83 @@ +package jetbrains.buildServer.buildTriggers.vcs.mercurial; + +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.MergeConflictException; +import jetbrains.buildServer.vcs.MergeOptions; +import jetbrains.buildServer.vcs.MergeSupport; +import jetbrains.buildServer.vcs.VcsException; +import jetbrains.buildServer.vcs.VcsRoot; +import org.jetbrains.annotations.NotNull; +import com.intellij.openapi.diagnostic.Logger; + +import java.io.File; +import java.util.List; + +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 MercurialVcsSupport myVcs; + private final HgVcsRootFactory myHgVcsRootFactory; + + public MercurialMergeSupport(@NotNull MercurialVcsSupport vcs, + @NotNull HgVcsRootFactory vcsRootFactory) { + vcs.addExtension(this); + myVcs = vcs; + myHgVcsRootFactory = vcsRootFactory; + } + + public void merge(@NotNull VcsRoot root, + @NotNull String srcRevision, + @NotNull String dstBranch, + @NotNull String message, + @NotNull MergeOptions options) throws VcsException { + File tmpDir = null; + try { + tmpDir = HgFileUtil.createTempDir(); + HgVcsRoot hgRoot = myHgVcsRootFactory.createHgRoot(root); + hgRoot.setCustomWorkingDir(tmpDir); + myVcs.syncRepository(hgRoot); + HgRepo repo = myVcs.createRepo(hgRoot); + repo.update().branch(dstBranch).call(); + + try { + repo.merge().revision(srcRevision).call(); + } catch (MergeConflictException e) { + List<String> conflicts = repo.resolve().call(); + throw new VcsException(getConflicsErrorMessage(conflicts)); + } + + repo.commit().message(message).call(); + + repo.push().toRepository(hgRoot.getRepository()).call(); + } catch (Exception e) { + if (e instanceof VcsException) + throw (VcsException) e; + throw new VcsException(e); + } finally { + deleteDir(tmpDir, LOG); + } + } + + @NotNull + private String getConflicsErrorMessage(@NotNull List<String> conflicts) { + if (conflicts.isEmpty()) + return "Merge failed, but no conflicts found"; + + if (conflicts.size() == 1) + return "Failed to merge file " + conflicts.get(0); + + StringBuilder message = new StringBuilder(); + message.append("Failed to merge files: "); + int i = 0; + for (; i < conflicts.size() && i < 3; i++) { + message.append(conflicts.get(i)).append("\n"); + } + if (i < conflicts.size()) + message.append(" and ").append(conflicts.size() - i).append(" more"); + + return message.toString(); + } +}
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Thu Aug 01 17:36:57 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Wed Aug 07 13:08:31 2013 +0400 @@ -61,7 +61,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 +89,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() { @@ -648,8 +652,6 @@ @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);
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialSupportBuilder.java Thu Aug 01 17:36:57 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialSupportBuilder.java Wed Aug 07 13:08:31 2013 +0400 @@ -42,7 +42,7 @@ }}); MercurialVcsSupport vcs = new MercurialVcsSupport(dispatcher, resetCacheManager, myConfig, hgPathProvider, repoFactory, mirrorManager, myHgRootFactory, testConnection, new SubrepoCheckoutRulesProviderImpl()); - vcs.setExtensions(myExtensions); + vcs.addExtensions(myExtensions); return vcs; }