Mercurial > hg > mercurial
changeset 751:3dc67825ce0d
Emulate fast-forward merge when dstBranch is reachable from srcRevision
author | Dmitry Neverov <dmitry.neverov@jetbrains.com> |
---|---|
date | Mon, 10 Feb 2014 21:22:31 +0100 |
parents | c33aefd02111 |
children | a0dfb5cd4477 6b7579d76fdf |
files | mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResult.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/exception/NothingToMergeException.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialMergeSupport.java |
diffstat | 3 files changed, 61 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResult.java Mon Feb 10 20:50:45 2014 +0100 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandResult.java Mon Feb 10 21:22:31 2014 +0100 @@ -211,6 +211,7 @@ checkConnectionRefused(stderr); checkAbandonedTransaction(stderr); checkMergeWithWorkDirAncestor(stderr); + checkNothingToMerge(stderr); } private void checkUnrelatedRepository(@NotNull final String stderr) throws UnrelatedRepositoryException { @@ -257,6 +258,11 @@ throw new MergeWithWorkingDirAncestor(); } + private void checkNothingToMerge(@NotNull final String stderr) throws NothingToMergeException { + if (stderr.startsWith("abort: nothing to merge")) + throw new NothingToMergeException(); + } + 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/exception/NothingToMergeException.java Mon Feb 10 21:22:31 2014 +0100 @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2014 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.command.exception; + +import jetbrains.buildServer.vcs.VcsException; + +public class NothingToMergeException extends VcsException { + + public NothingToMergeException() { + super("Nothing to merge"); + } + +}
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialMergeSupport.java Mon Feb 10 20:50:45 2014 +0100 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialMergeSupport.java Mon Feb 10 21:22:31 2014 +0100 @@ -21,6 +21,7 @@ import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.PushCommand; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.MergeConflictException; import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.MergeWithWorkingDirAncestor; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.exception.NothingToMergeException; import jetbrains.buildServer.vcs.*; import org.jetbrains.annotations.NotNull; @@ -104,6 +105,7 @@ .setBranch(dstBranch).checkout(); HgRepo repo = myHgRepoFactory.createRepo(hgRoot, tmpDir); + boolean bookmark = isBookmark(repo, dstBranch); try { repo.merge().withMergeTool(myConfig.getMergeTool()).revision(srcRevision).call(); } catch (MergeConflictException e) { @@ -116,22 +118,26 @@ ", revision " + srcRevision + ", destination " + dstBranch, e); return MergeResult.createMergeNotPerformedResult("Revision " + srcRevision + " is already merged into " + dstBranch); + } catch (NothingToMergeException e) { + //happens when revision of the dstBranch is merged into srcRevision + if (bookmark) { + //emulate fast-forward merge + repo.updateBookmark().name(dstBranch).setRevision(srcRevision).call(); + push(root, srcRevision, dstBranch, hgRoot, repo, bookmark); + LOG.info("Merge successfully finished in root " + root + ", revision " + srcRevision + ", destination " + dstBranch); + return MergeResult.createMergeSuccessResult(); + } else { + return MergeResult.createMergeError("Revision of branch " + dstBranch + " is reachable from " + srcRevision); + } } repo.commit().by(hgRoot.getUserForTag()).message(message).call(); - boolean bookmark = isBookmark(repo, dstBranch); + if (bookmark) repo.updateBookmark().name(dstBranch).call(); - try { - PushCommand push = repo.push().toRepository(hgRoot.getRepository()); - if (bookmark) - push.bookmark(dstBranch); - push.call(); - } catch (VcsException e) { - LOG.info("Error while pushing a merge commit, root " + root + ", revision " + srcRevision + ", destination " + dstBranch, e); - throw e; - } + push(root, srcRevision, dstBranch, hgRoot, repo, bookmark); + LOG.info("Merge successfully finished in root " + root + ", revision " + srcRevision + ", destination " + dstBranch); return MergeResult.createMergeSuccessResult(); } catch (Exception e) { @@ -143,6 +149,18 @@ } } + private void push(VcsRoot root, String srcRevision, String dstBranch, HgVcsRoot hgRoot, HgRepo repo, boolean bookmark) throws VcsException { + try { + PushCommand push = repo.push().toRepository(hgRoot.getRepository()); + if (bookmark) + push.bookmark(dstBranch); + push.call(); + } catch (VcsException e) { + LOG.info("Error while pushing a merge commit, root " + root + ", revision " + srcRevision + ", destination " + dstBranch, e); + throw e; + } + } + private boolean isBookmark(@NotNull HgRepo repo, @NotNull String branch) throws VcsException { if (repo.branches().call().keySet().contains(branch))