Set the commit message to be used for the merge commit (in case one is created) Bug: 442886 Change-Id: Ie5ecc13822faa366f00b3daa07f74c8441cae195 Signed-off-by: Axel Richard <axel.richard@obeo.fr> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>tags/v3.5.0.201409071800-rc1
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright (C) 2012, IBM Corporation and others. | |||
* Copyright (C) 2012, 2014 IBM Corporation and others. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
@@ -45,9 +45,12 @@ package org.eclipse.jgit.pgm; | |||
import static org.junit.Assert.assertArrayEquals; | |||
import static org.junit.Assert.assertEquals; | |||
import java.util.Iterator; | |||
import org.eclipse.jgit.api.Git; | |||
import org.eclipse.jgit.lib.CLIRepositoryTestCase; | |||
import org.eclipse.jgit.merge.MergeStrategy; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
@@ -209,4 +212,24 @@ public class MergeTest extends CLIRepositoryTestCase { | |||
assertEquals("fatal: Not possible to fast-forward, aborting.", | |||
execute("git merge master --ff-only")[0]); | |||
} | |||
@Test | |||
public void testMergeWithUserMessage() throws Exception { | |||
git.branchCreate().setName("side").call(); | |||
writeTrashFile("master", "content"); | |||
git.add().addFilepattern("master").call(); | |||
git.commit().setMessage("master commit").call(); | |||
git.checkout().setName("side").call(); | |||
writeTrashFile("side", "content"); | |||
git.add().addFilepattern("side").call(); | |||
git.commit().setMessage("side commit").call(); | |||
assertEquals("Merge made by the '" + MergeStrategy.RECURSIVE.getName() | |||
+ "' strategy.", | |||
execute("git merge master -m \"user message\"")[0]); | |||
Iterator<RevCommit> it = git.log().call().iterator(); | |||
RevCommit newHead = it.next(); | |||
assertEquals("user message", newHead.getFullMessage()); | |||
} | |||
} |
@@ -298,6 +298,7 @@ usage_mergeNoFf=Create a merge commit even when the merge resolves as a fast-for | |||
usage_mergeFfOnly=Refuse to merge and exit with a non-zero status unless the current HEAD is already up-to-date or the merge can be resolved as a fast-forward. | |||
usage_mergeRef=Ref to be merged | |||
usage_mergeStrategy=Use the given merge strategy. Can be supplied more than once to specify them in the order they should be tried. If there is no -s option, the recursive strategy is used. Currently the following strategies are supported: ours, theirs, simple-two-way-in-core, resolve, recursive | |||
usage_message=Set the commit message to be used for the merge commit (in case one is created). | |||
usage_moveRenameABranch=move/rename a branch | |||
usage_nameStatus=show only name and status of files | |||
usage_noCheckoutAfterClone=no checkout of HEAD is performed after the clone is complete |
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright (C) 2011, Christian Halstrick <christian.halstrick@sap.com> | |||
* Copyright (C) 2011, 2014 Christian Halstrick <christian.halstrick@sap.com> | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
@@ -98,6 +98,9 @@ class Merge extends TextBuiltin { | |||
ff = FastForwardMode.FF_ONLY; | |||
} | |||
@Option(name = "-m", usage = "usage_message") | |||
private String message; | |||
@Override | |||
protected void run() throws Exception { | |||
if (squash && ff == FastForwardMode.NO_FF) | |||
@@ -125,6 +128,10 @@ class Merge extends TextBuiltin { | |||
mergeCmd.include(srcRef); | |||
else | |||
mergeCmd.include(src); | |||
if (message != null) | |||
mergeCmd.setMessage(message); | |||
MergeResult result; | |||
try { | |||
result = mergeCmd.call(); |
@@ -1,6 +1,6 @@ | |||
/* | |||
* Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com> | |||
* Copyright (C) 2010-2012, Christian Halstrick <christian.halstrick@sap.com> | |||
* Copyright (C) 2010-2014, Christian Halstrick <christian.halstrick@sap.com> | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
@@ -1566,6 +1566,69 @@ public class MergeCommandTest extends RepositoryTestCase { | |||
assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus()); | |||
} | |||
@Test | |||
public void testMergeWithMessageOption() throws Exception { | |||
Git git = new Git(db); | |||
writeTrashFile("a", "1\na\n3\n"); | |||
git.add().addFilepattern("a").call(); | |||
RevCommit initialCommit = git.commit().setMessage("initial").call(); | |||
createBranch(initialCommit, "refs/heads/side"); | |||
checkoutBranch("refs/heads/side"); | |||
writeTrashFile("b", "1\nb\n3\n"); | |||
git.add().addFilepattern("b").call(); | |||
git.commit().setMessage("side").call(); | |||
checkoutBranch("refs/heads/master"); | |||
writeTrashFile("c", "1\nc\n3\n"); | |||
git.add().addFilepattern("c").call(); | |||
git.commit().setMessage("main").call(); | |||
Ref sideBranch = db.getRef("side"); | |||
git.merge().include(sideBranch).setStrategy(MergeStrategy.RESOLVE) | |||
.setMessage("user message").call(); | |||
assertNull(db.readMergeCommitMsg()); | |||
Iterator<RevCommit> it = git.log().call().iterator(); | |||
RevCommit newHead = it.next(); | |||
assertEquals("user message", newHead.getFullMessage()); | |||
} | |||
@Test | |||
public void testMergeConflictWithMessageOption() throws Exception { | |||
Git git = new Git(db); | |||
writeTrashFile("a", "1\na\n3\n"); | |||
git.add().addFilepattern("a").call(); | |||
RevCommit initialCommit = git.commit().setMessage("initial").call(); | |||
createBranch(initialCommit, "refs/heads/side"); | |||
checkoutBranch("refs/heads/side"); | |||
writeTrashFile("a", "1\na(side)\n3\n"); | |||
git.add().addFilepattern("a").call(); | |||
git.commit().setMessage("side").call(); | |||
checkoutBranch("refs/heads/master"); | |||
writeTrashFile("a", "1\na(main)\n3\n"); | |||
git.add().addFilepattern("a").call(); | |||
git.commit().setMessage("main").call(); | |||
Ref sideBranch = db.getRef("side"); | |||
git.merge().include(sideBranch).setStrategy(MergeStrategy.RESOLVE) | |||
.setMessage("user message").call(); | |||
assertEquals("user message\n\nConflicts:\n\ta\n", | |||
db.readMergeCommitMsg()); | |||
} | |||
private static void setExecutable(Git git, String path, boolean executable) { | |||
FS.DETECTED.setExecute( | |||
new File(git.getRepository().getWorkTree(), path), executable); |
@@ -1,6 +1,6 @@ | |||
/* | |||
* Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com> | |||
* Copyright (C) 2010-2012, Stefan Lay <stefan.lay@sap.com> | |||
* Copyright (C) 2010-2014, Stefan Lay <stefan.lay@sap.com> | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
@@ -104,6 +104,8 @@ public class MergeCommand extends GitCommand<MergeResult> { | |||
private FastForwardMode fastForwardMode; | |||
private String message; | |||
/** | |||
* The modes available for fast forward merges corresponding to the | |||
* <code>--ff</code>, <code>--no-ff</code> and <code>--ff-only</code> | |||
@@ -313,7 +315,10 @@ public class MergeCommand extends GitCommand<MergeResult> { | |||
} | |||
String mergeMessage = ""; //$NON-NLS-1$ | |||
if (!squash) { | |||
mergeMessage = new MergeMessageFormatter().format( | |||
if (message != null) | |||
mergeMessage = message; | |||
else | |||
mergeMessage = new MergeMessageFormatter().format( | |||
commits, head); | |||
repo.writeMergeCommitMsg(mergeMessage); | |||
repo.writeMergeHeads(Arrays.asList(ref.getObjectId())); | |||
@@ -565,4 +570,18 @@ public class MergeCommand extends GitCommand<MergeResult> { | |||
this.commit = Boolean.valueOf(commit); | |||
return this; | |||
} | |||
/** | |||
* Set the commit message to be used for the merge commit (in case one is | |||
* created) | |||
* | |||
* @param message | |||
* the message to be used for the merge commit | |||
* @return {@code this} | |||
* @since 3.5 | |||
*/ | |||
public MergeCommand setMessage(String message) { | |||
this.message = message; | |||
return this; | |||
} | |||
} |