Add --squash option to org.eclipse.jgit.pgm.Merge

Change-Id: Ifd20b6f4731cfa71319145cac7b464aa53db18b8
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/MergeTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/MergeTest.java
index b33fc0f..87a2c85 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/MergeTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/MergeTest.java
@@ -43,6 +43,7 @@
 package org.eclipse.jgit.pgm;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
 
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.lib.CLIRepositoryTestCase;
@@ -51,11 +52,15 @@
 import org.junit.Test;
 
 public class MergeTest extends CLIRepositoryTestCase {
+
+	private Git git;
+
 	@Override
 	@Before
 	public void setUp() throws Exception {
 		super.setUp();
-		new Git(db).commit().setMessage("initial commit").call();
+		git = new Git(db);
+		git.commit().setMessage("initial commit").call();
 	}
 
 	@Test
@@ -64,30 +69,55 @@ public void testMergeSelf() throws Exception {
 	}
 
 	@Test
+	public void testSquashSelf() throws Exception {
+		assertEquals(" (nothing to squash)Already up-to-date.",
+				execute("git merge master --squash")[0]);
+	}
+
+	@Test
 	public void testFastForward() throws Exception {
-		new Git(db).commit().setMessage("initial commit").call();
-		new Git(db).branchCreate().setName("side").call();
+		git.branchCreate().setName("side").call();
 		writeTrashFile("file", "master");
-		new Git(db).add().addFilepattern("file").call();
-		new Git(db).commit().setMessage("commit").call();
-		new Git(db).checkout().setName("side").call();
+		git.add().addFilepattern("file").call();
+		git.commit().setMessage("commit").call();
+		git.checkout().setName("side").call();
 
 		assertEquals("Fast-forward", execute("git merge master")[0]);
 	}
 
 	@Test
 	public void testMerge() throws Exception {
-		new Git(db).commit().setMessage("initial commit").call();
-		new Git(db).branchCreate().setName("side").call();
+		git.branchCreate().setName("side").call();
 		writeTrashFile("master", "content");
-		new Git(db).add().addFilepattern("master").call();
-		new Git(db).commit().setMessage("master commit").call();
-		new Git(db).checkout().setName("side").call();
+		git.add().addFilepattern("master").call();
+		git.commit().setMessage("master commit").call();
+		git.checkout().setName("side").call();
 		writeTrashFile("side", "content");
-		new Git(db).add().addFilepattern("side").call();
-		new Git(db).commit().setMessage("side commit").call();
+		git.add().addFilepattern("side").call();
+		git.commit().setMessage("side commit").call();
 
 		assertEquals("Merge made by the '" + MergeStrategy.RESOLVE.getName()
 				+ "' strategy.", execute("git merge master")[0]);
 	}
+
+	@Test
+	public void testSquash() throws Exception {
+		git.branchCreate().setName("side").call();
+		writeTrashFile("file1", "content1");
+		git.add().addFilepattern("file1").call();
+		git.commit().setMessage("file1 commit").call();
+		writeTrashFile("file2", "content2");
+		git.add().addFilepattern("file2").call();
+		git.commit().setMessage("file2 commit").call();
+		git.checkout().setName("side").call();
+		writeTrashFile("side", "content");
+		git.add().addFilepattern("side").call();
+		git.commit().setMessage("side commit").call();
+
+		assertArrayEquals(
+				new String[] { "Squash commit -- not updating HEAD",
+						"Automatic merge went well; stopped before committing as requested",
+						"" },
+				execute("git merge master --squash"));
+	}
 }
diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties
index 5e38c04..8bbcf5e 100644
--- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties
+++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties
@@ -66,6 +66,7 @@
 mergeConflict=CONFLICT(content): Merge conflict in {0}
 mergeFailed=Automatic merge failed; fix conflicts and then commit the result
 mergeMadeBy=Merge made by the ''{0}'' strategy.
+mergedSquashed=Squash commit -- not updating HEAD\nAutomatic merge went well; stopped before committing as requested
 metaVar_DAG=DAG
 metaVar_KEY=KEY
 metaVar_arg=ARG
@@ -127,6 +128,7 @@
 notAnObject={0} is not an object
 notFound=!! NOT FOUND !!
 noteObjectTooLargeToPrint=Note object {0} too large to print
+nothingToSquash=\ (nothing to squash)
 notOnAnyBranch=Not currently on any branch.
 onBranch=On branch {0}
 onBranchToBeBorn=You are on a branch yet to be born
@@ -262,6 +264,7 @@
 usage_showPatch=display patch
 usage_showRefNamesMatchingCommits=Show ref names matching commits
 usage_showNotes=Add this ref to the list of note branches from which notes are displayed
+usage_squash=Squash commits as if a real merge happened, but do not make a commit or move the HEAD.
 usage_srcPrefix=show the source prefix instead of "a/"
 usage_symbolicVersionForTheProject=Symbolic version for the project
 usage_synchronizeIPZillaData=Synchronize IPZilla data
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java
index a5756ce..86ec92d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java
@@ -133,6 +133,7 @@ public static String formatLine(String line) {
 	/***/ public String mergeConflict;
 	/***/ public String mergeFailed;
 	/***/ public String mergeMadeBy;
+	/***/ public String mergedSquashed;
 	/***/ public String metaVar_KEY;
 	/***/ public String metaVar_arg;
 	/***/ public String metaVar_author;
@@ -189,6 +190,7 @@ public static String formatLine(String line) {
 	/***/ public String notFound;
 	/***/ public String notOnAnyBranch;
 	/***/ public String noteObjectTooLargeToPrint;
+	/***/ public String nothingToSquash;
 	/***/ public String onBranchToBeBorn;
 	/***/ public String onBranch;
 	/***/ public String onlyOneMetaVarExpectedIn;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java
index 8c769e6..728866d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java
@@ -60,6 +60,9 @@ class Merge extends TextBuiltin {
 	@Option(name = "--strategy", aliases = { "-s" }, usage = "usage_mergeStrategy")
 	private String strategyName;
 
+	@Option(name = "--squash", usage = "usage_squash")
+	private boolean squash;
+
 	private MergeStrategy mergeStrategy = MergeStrategy.RESOLVE;
 
 	@Argument(required = true)
@@ -83,10 +86,12 @@ protected void run() throws Exception {
 
 		Git git = new Git(db);
 		MergeResult result = git.merge().setStrategy(mergeStrategy)
-				.include(src).call();
+				.setSquash(squash).include(src).call();
 
 		switch (result.getMergeStatus()) {
 		case ALREADY_UP_TO_DATE:
+			if (squash)
+				outw.print(CLIText.get().nothingToSquash);
 			outw.println(CLIText.get().alreadyUpToDate);
 			break;
 		case FAST_FORWARD:
@@ -117,6 +122,9 @@ protected void run() throws Exception {
 			outw.println(MessageFormat.format(CLIText.get().mergeMadeBy,
 					mergeStrategy.getName()));
 			break;
+		case MERGED_SQUASHED:
+			outw.println(CLIText.get().mergedSquashed);
+			break;
 		case NOT_SUPPORTED:
 			outw.println(MessageFormat.format(
 					CLIText.get().unsupportedOperation, result.toString()));