]> source.dussan.org Git - jgit.git/commitdiff
Add the no-commit option to MergeCommand 45/4945/6
authorTomasz Zarna <tomasz.zarna@tasktop.com>
Thu, 12 Jan 2012 17:32:53 +0000 (18:32 +0100)
committerTomasz Zarna <tomasz.zarna@tasktop.com>
Thu, 4 Apr 2013 13:11:49 +0000 (15:11 +0200)
Added also tests and the associated option for the command line Merge
command.

Bug: 335091
Change-Id: Ie321c572284a6f64765a81674089fc408a10d059
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/lib/CLIRepositoryTestCase.java
org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/MergeTest.java
org.eclipse.jgit.pgm/.settings/.api_filters
org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties
org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java
org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java
org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java

index 755174bcbc3c96710ed75ab3d9ad8b42b006e1e2..a328baec2780ed11229dcf5766155e6e06af09ce 100644 (file)
@@ -49,7 +49,6 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.jgit.internal.storage.file.FileRepository;
 import org.eclipse.jgit.junit.JGitTestUtil;
 import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
 import org.eclipse.jgit.pgm.CLIGitCommand;
@@ -57,7 +56,7 @@ import org.junit.Before;
 
 public class CLIRepositoryTestCase extends LocalDiskRepositoryTestCase {
        /** Test repository, initialized for this test case. */
-       protected FileRepository db;
+       protected Repository db;
 
        /** Working directory of {@link #db}. */
        protected File trash;
@@ -165,7 +164,7 @@ public class CLIRepositoryTestCase extends LocalDiskRepositoryTestCase {
                assertEquals(toText(expected), toText(actual));
        }
 
-       private String toText(String[] lines) {
+       private static String toText(String[] lines) {
                StringBuilder b = new StringBuilder();
                for (String s : lines) {
                        b.append(s);
index 28a107bcb1efe42d2a17e4bfe7509abe9dc9332f..d0b363baa9ebbdfb16720aabd2f600c273e5ffa8 100644 (file)
@@ -101,6 +101,40 @@ public class MergeTest extends CLIRepositoryTestCase {
                                + "' strategy.", execute("git merge master")[0]);
        }
 
+       @Test
+       public void testMergeNoCommit() 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(
+                               "Automatic merge went well; stopped before committing as requested",
+                               execute("git merge --no-commit master")[0]);
+       }
+
+       @Test
+       public void testMergeNoCommitSquash() 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();
+
+               assertArrayEquals(
+                               new String[] {
+                                               "Squash commit -- not updating HEAD",
+                                               "Automatic merge went well; stopped before committing as requested",
+                                               "" }, execute("git merge --no-commit --squash master"));
+       }
+
        @Test
        public void testSquash() throws Exception {
                git.branchCreate().setName("side").call();
index 5e044ee2ada87cf8654b88c21bf6ae03dbd6ecbc..35db29c922e48369fd5da53cc6c10805717371ea 100644 (file)
@@ -1,6 +1,11 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <component id="org.eclipse.jgit.pgm" version="2">
     <resource path="src/org/eclipse/jgit/pgm/CLIText.java" type="org.eclipse.jgit.pgm.CLIText">
+        <filter id="1143996420">
+            <message_arguments>
+                <message_argument value="mergeWentWellStoppedBeforeCommitting"/>
+            </message_arguments>
+        </filter>
         <filter id="1143996420">
             <message_arguments>
                 <message_argument value="noSuchRemoteRef"/>
index d9684054c18bcef2a426ff3b36abf77f01717041..eed05e89f54dee2b7d402b8ae223f57861ad389d 100644 (file)
@@ -68,6 +68,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
+mergeWentWellStoppedBeforeCommitting=Automatic merge went well; stopped before committing as requested
 metaVar_DAG=DAG
 metaVar_KEY=KEY
 metaVar_archiveFormat=format
@@ -248,6 +249,7 @@ usage_manageReflogInformation=Manage reflog information
 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 resolve strategy is used. Currently the following strategies are supported: ours, theirs, simple-two-way-in-core, resolve
 usage_moveRenameABranch=move/rename a branch
 usage_nameStatus=show only name and status of files
+usage_noCommit=Don't commit after a successful merge
 usage_noPrefix=do not show any source or destination prefix
 usage_noRenames=disable rename detection
 usage_noShowStandardNotes=Disable showing notes from the standard /refs/notes/commits branch
index 807fe39db999d6d437dd0da2fa48716f69f05f21..64bd18e867e2499c5dc11d0c96fdfc07f1912642 100644 (file)
@@ -137,6 +137,7 @@ public class CLIText extends TranslationBundle {
        /***/ public String mergeFailed;
        /***/ public String mergeMadeBy;
        /***/ public String mergedSquashed;
+       /***/ public String mergeWentWellStoppedBeforeCommitting;
        /***/ public String metaVar_KEY;
        /***/ public String metaVar_archiveFormat;
        /***/ public String metaVar_arg;
index 7eaa5fa3510787cac736c9c6b7148f2f44cbb30e..97198259d31eb033c714da3a4d5da64faf97ed82 100644 (file)
@@ -71,6 +71,9 @@ class Merge extends TextBuiltin {
        @Option(name = "--squash", usage = "usage_squash")
        private boolean squash;
 
+       @Option(name = "--no-commit", usage = "usage_noCommit")
+       private boolean noCommit = false;
+
        private MergeStrategy mergeStrategy = MergeStrategy.RESOLVE;
 
        @Argument(required = true)
@@ -111,7 +114,7 @@ class Merge extends TextBuiltin {
                Ref oldHead = db.getRef(Constants.HEAD);
                Git git = new Git(db);
                MergeCommand mergeCmd = git.merge().setStrategy(mergeStrategy)
-                               .setSquash(squash).setFastForward(ff);
+                               .setSquash(squash).setFastForward(ff).setCommit(!noCommit);
                if (srcRef != null)
                        mergeCmd.include(srcRef);
                else
@@ -160,8 +163,12 @@ class Merge extends TextBuiltin {
                                name = "recursive"; //$NON-NLS-1$
                        outw.println(MessageFormat.format(CLIText.get().mergeMadeBy, name));
                        break;
+               case MERGED_NOT_COMMITTED:
+                       outw.println(CLIText.get().mergeWentWellStoppedBeforeCommitting);
+                       break;
                case MERGED_SQUASHED:
                case FAST_FORWARD_SQUASHED:
+               case MERGED_SQUASHED_NOT_COMMITTED:
                        outw.println(CLIText.get().mergedSquashed);
                        break;
                case ABORTED:
index cf9573e44c21e354faa3e02830e7d718a68f663c..ba0847bd8d805b822e58b71928eb3db1fa61f86d 100644 (file)
@@ -141,6 +141,28 @@ public class MergeCommandTest extends RepositoryTestCase {
                                db.getReflogReader(db.getBranch()).getLastEntry().getComment());
        }
 
+       @Test
+       public void testFastForwardNoCommit() throws Exception {
+               Git git = new Git(db);
+               RevCommit first = git.commit().setMessage("initial commit").call();
+               createBranch(first, "refs/heads/branch1");
+
+               RevCommit second = git.commit().setMessage("second commit").call();
+
+               checkoutBranch("refs/heads/branch1");
+
+               MergeResult result = git.merge().include(db.getRef(Constants.MASTER))
+                               .setCommit(false).call();
+
+               assertEquals(MergeResult.MergeStatus.FAST_FORWARD,
+                               result.getMergeStatus());
+               assertEquals(second, result.getNewHead());
+               assertEquals("merge refs/heads/master: Fast-forward", db
+                               .getReflogReader(Constants.HEAD).getLastEntry().getComment());
+               assertEquals("merge refs/heads/master: Fast-forward", db
+                               .getReflogReader(db.getBranch()).getLastEntry().getComment());
+       }
+
        @Test
        public void testFastForwardWithFiles() throws Exception {
                Git git = new Git(db);
@@ -234,6 +256,31 @@ public class MergeCommandTest extends RepositoryTestCase {
                                db.getReflogReader(db.getBranch()).getLastEntry().getComment());
        }
 
+       @Theory
+       public void testMergeSuccessAllStrategiesNoCommit(
+                       MergeStrategy mergeStrategy) throws Exception {
+               Git git = new Git(db);
+
+               RevCommit first = git.commit().setMessage("first").call();
+               createBranch(first, "refs/heads/side");
+
+               writeTrashFile("a", "a");
+               git.add().addFilepattern("a").call();
+               git.commit().setMessage("second").call();
+
+               checkoutBranch("refs/heads/side");
+               writeTrashFile("b", "b");
+               git.add().addFilepattern("b").call();
+               RevCommit thirdCommit = git.commit().setMessage("third").call();
+
+               MergeResult result = git.merge().setStrategy(mergeStrategy)
+                               .setCommit(false)
+                               .include(db.getRef(Constants.MASTER)).call();
+               assertEquals(MergeStatus.MERGED_NOT_COMMITTED, result.getMergeStatus());
+               assertEquals(db.getRef(Constants.HEAD).getTarget().getObjectId(),
+                               thirdCommit.getId());
+       }
+
        @Test
        public void testContentMerge() throws Exception {
                Git git = new Git(db);
@@ -480,6 +527,56 @@ public class MergeCommandTest extends RepositoryTestCase {
                // test index state
        }
 
+       @Test
+       public void testSuccessfulContentMergeNoCommit() throws Exception {
+               Git git = new Git(db);
+
+               writeTrashFile("a", "1\na\n3\n");
+               writeTrashFile("b", "1\nb\n3\n");
+               writeTrashFile("c/c/c", "1\nc\n3\n");
+               git.add().addFilepattern("a").addFilepattern("b")
+                               .addFilepattern("c/c/c").call();
+               RevCommit initialCommit = git.commit().setMessage("initial").call();
+
+               createBranch(initialCommit, "refs/heads/side");
+               checkoutBranch("refs/heads/side");
+
+               writeTrashFile("a", "1(side)\na\n3\n");
+               writeTrashFile("b", "1\nb(side)\n3\n");
+               git.add().addFilepattern("a").addFilepattern("b").call();
+               RevCommit secondCommit = git.commit().setMessage("side").call();
+
+               assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
+               checkoutBranch("refs/heads/master");
+               assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));
+
+               writeTrashFile("a", "1\na\n3(main)\n");
+               writeTrashFile("c/c/c", "1\nc(main)\n3\n");
+               git.add().addFilepattern("a").addFilepattern("c/c/c").call();
+               RevCommit thirdCommit = git.commit().setMessage("main").call();
+
+               MergeResult result = git.merge().include(secondCommit.getId())
+                               .setCommit(false)
+                               .setStrategy(MergeStrategy.RESOLVE).call();
+               assertEquals(MergeStatus.MERGED_NOT_COMMITTED, result.getMergeStatus());
+               assertEquals(db.getRef(Constants.HEAD).getTarget().getObjectId(),
+                               thirdCommit.getId());
+
+               assertEquals("1(side)\na\n3(main)\n", read(new File(db.getWorkTree(),
+                               "a")));
+               assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
+               assertEquals("1\nc(main)\n3\n",
+                               read(new File(db.getWorkTree(), "c/c/c")));
+
+               assertEquals(null, result.getConflicts());
+
+               assertEquals(2, result.getMergedCommits().length);
+               assertEquals(thirdCommit, result.getMergedCommits()[0]);
+               assertEquals(secondCommit, result.getMergedCommits()[1]);
+               assertNull(result.getNewHead());
+               assertEquals(RepositoryState.MERGING_RESOLVED, db.getRepositoryState());
+       }
+
        @Test
        public void testSuccessfulContentMergeAndDirtyworkingTree()
                        throws Exception {
@@ -1345,6 +1442,7 @@ public class MergeCommandTest extends RepositoryTestCase {
 
                assertEquals(MergeStatus.FAST_FORWARD, result.getMergeStatus());
        }
+
        @Test
        public void testNoFastForward() throws Exception {
                Git git = new Git(db);
@@ -1362,6 +1460,33 @@ public class MergeCommandTest extends RepositoryTestCase {
                assertEquals(MergeStatus.MERGED, result.getMergeStatus());
        }
 
+       @Test
+       public void testNoFastForwardNoCommit() throws Exception {
+               // given
+               Git git = new Git(db);
+               RevCommit initialCommit = git.commit().setMessage("initial commit")
+                               .call();
+               createBranch(initialCommit, "refs/heads/branch1");
+               RevCommit secondCommit = git.commit().setMessage("second commit")
+                               .call();
+               checkoutBranch("refs/heads/branch1");
+
+               // when
+               MergeCommand merge = git.merge();
+               merge.setFastForward(FastForwardMode.NO_FF);
+               merge.include(db.getRef(Constants.MASTER));
+               merge.setCommit(false);
+               MergeResult result = merge.call();
+
+               // then
+               assertEquals(MergeStatus.MERGED_NOT_COMMITTED, result.getMergeStatus());
+               assertEquals(2, result.getMergedCommits().length);
+               assertEquals(initialCommit, result.getMergedCommits()[0]);
+               assertEquals(secondCommit, result.getMergedCommits()[1]);
+               assertNull(result.getNewHead());
+               assertEquals(RepositoryState.MERGING_RESOLVED, db.getRepositoryState());
+       }
+
        @Test
        public void testFastForwardOnlyNotPossible() throws Exception {
                Git git = new Git(db);
index 6c6aa7b5c5e1ff0d520d2a5dd5f98be712d6faed..8f6e9cbb5d4706128ac38566606485ffb7c30e3c 100644 (file)
@@ -195,6 +195,8 @@ public class MergeCommand extends GitCommand<MergeResult> {
                }
        }
 
+       private boolean commit = true;
+
        /**
         * @param repo
         */
@@ -327,7 +329,7 @@ public class MergeCommand extends GitCommand<MergeResult> {
                                if (merger instanceof ResolveMerger) {
                                        ResolveMerger resolveMerger = (ResolveMerger) merger;
                                        resolveMerger.setCommitNames(new String[] {
-                                                       "BASE", "HEAD", ref.getName() }); //$NON-NLS-1$
+                                                       "BASE", "HEAD", ref.getName() }); //$NON-NLS-1$ //$NON-NLS-2$
                                        resolveMerger.setWorkingTreeIterator(new FileTreeIterator(repo));
                                        noProblems = merger.merge(headCommit, srcCommit);
                                        lowLevelResults = resolveMerger
@@ -350,18 +352,26 @@ public class MergeCommand extends GitCommand<MergeResult> {
                                        dco.checkout();
 
                                        String msg = null;
-                                       RevCommit newHead = null;
+                                       ObjectId newHeadId = null;
                                        MergeStatus mergeStatus = null;
-                                       if (!squash) {
-                                               newHead = new Git(getRepository()).commit()
-                                                       .setReflogComment(refLogMessage.toString()).call();
+                                       if (!commit && squash) {
+                                               mergeStatus = MergeStatus.MERGED_SQUASHED_NOT_COMMITTED;
+                                       }
+                                       if (!commit && !squash) {
+                                               mergeStatus = MergeStatus.MERGED_NOT_COMMITTED;
+                                       }
+                                       if (commit && !squash) {
+                                               newHeadId = new Git(getRepository()).commit()
+                                                               .setReflogComment(refLogMessage.toString())
+                                                               .call().getId();
                                                mergeStatus = MergeStatus.MERGED;
-                                       } else {
+                                       }
+                                       if (commit && squash) {
                                                msg = JGitText.get().squashCommitNotUpdatingHEAD;
-                                               newHead = headCommit;
+                                               newHeadId = headCommit.getId();
                                                mergeStatus = MergeStatus.MERGED_SQUASHED;
                                        }
-                                       return new MergeResult(newHead.getId(), null,
+                                       return new MergeResult(newHeadId, null,
                                                        new ObjectId[] { headCommit.getId(),
                                                                        srcCommit.getId() }, mergeStatus,
                                                        mergeStrategy, null, msg);
@@ -521,4 +531,23 @@ public class MergeCommand extends GitCommand<MergeResult> {
                this.fastForwardMode = fastForwardMode;
                return this;
        }
+
+       /**
+        * Controls whether the merge command should automatically commit after a
+        * successful merge
+        *
+        * @param commit
+        *            <code>true</code> if this command should commit (this is the
+        *            default behavior). <code>false</code> if this command should
+        *            not commit. In case the merge was successful but this flag was
+        *            set to <code>false</code> a {@link MergeResult} with type
+        *            {@link MergeResult} with status
+        *            {@link MergeStatus#MERGED_NOT_COMMITTED} is returned
+        * @return {@code this}
+        * @since 3.0
+        */
+       public MergeCommand setCommit(boolean commit) {
+               this.commit = commit;
+               return this;
+       }
 }
index 82272168aa71fbaf9980f73e6972c55979d7b2e4..c34ba6b2d1be45bb851e40a8d16aa5db54910a69 100644 (file)
@@ -141,6 +141,20 @@ public class MergeResult {
                                return true;
                        }
                },
+               /**
+                * @since 3.0
+                */
+               MERGED_SQUASHED_NOT_COMMITTED {
+                       @Override
+                       public String toString() {
+                               return "Merged-squashed-not-committed";
+                       }
+
+                       @Override
+                       public boolean isSuccessful() {
+                               return true;
+                       }
+               },
                /** */
                CONFLICTING {
                        @Override
@@ -167,6 +181,19 @@ public class MergeResult {
                                return false;
                        }
                },
+               /**
+                * @since 3.0
+                **/
+               MERGED_NOT_COMMITTED {
+                       public String toString() {
+                               return "MergedNotCommited";
+                       }
+
+                       @Override
+                       public boolean isSuccessful() {
+                               return true;
+                       }
+               },
                /** */
                NOT_SUPPORTED {
                        @Override