]> source.dussan.org Git - jgit.git/commitdiff
Added Merge command to the CLI 20/320/7
authorChristian Halstrick <christian.halstrick@sap.com>
Fri, 5 Mar 2010 08:31:33 +0000 (09:31 +0100)
committerChris Aniszczyk <caniszczyk@gmail.com>
Tue, 29 Mar 2011 17:27:45 +0000 (12:27 -0500)
This merge command accepts the merge strategy as option and uses the
resolve strategy as default. It expects exactly one other
revision which is merged with current head.

Change-Id: Ia8c188b93ade4afabe6a9ccf267faf045f359a3a
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin
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 [new file with mode: 0644]

index 9825031ce22638e7756c5749a28647673580bb61..484d32d418eb29a31d02e54ed61319687d01584d 100644 (file)
@@ -14,6 +14,7 @@ Import-Package: org.eclipse.jgit.api;version="[0.12.0,0.13.0)",
  org.eclipse.jgit.errors;version="[0.12.0,0.13.0)",
  org.eclipse.jgit.iplog;version="[0.12.0,0.13.0)",
  org.eclipse.jgit.lib;version="[0.12.0,0.13.0)",
+ org.eclipse.jgit.merge;version="0.12.0",
  org.eclipse.jgit.nls;version="[0.12.0,0.13.0)",
  org.eclipse.jgit.notes;version="[0.12.0,0.13.0)",
  org.eclipse.jgit.revplot;version="[0.12.0,0.13.0)",
index c929578de266f37830f32889ed3d8d8b38ed32d3..1586528c6c56d0370edb3de355f1e804eb1f7813 100644 (file)
@@ -14,6 +14,7 @@ org.eclipse.jgit.pgm.Init
 org.eclipse.jgit.pgm.Log
 org.eclipse.jgit.pgm.LsRemote
 org.eclipse.jgit.pgm.LsTree
+org.eclipse.jgit.pgm.Merge
 org.eclipse.jgit.pgm.MergeBase
 org.eclipse.jgit.pgm.Push
 org.eclipse.jgit.pgm.ReceivePack
index 718c57ad2e1c968b88d11dc803c076b74079440a..98fbd7fbc49526dfea1a40e49bff632061601d69 100644 (file)
@@ -19,9 +19,11 @@ cannotChekoutNoHeadsAdvertisedByRemote=cannot checkout; no HEAD advertised by re
 cannotCreateCommand=Cannot create command {0}
 cannotCreateOutputStream=cannot create output stream
 cannotDeatchHEAD=Cannot deatch HEAD
+cannotDeleteFile=error: The following file could not be deleted:
 cannotDeleteTheBranchWhichYouAreCurrentlyOn=Cannot delete the branch '{0}' which you are currently on.
 cannotGuessLocalNameFrom=cannot guess local name from {0}
 cannotLock=Cannot lock {0}
+cannotMergeDetachedHead=Cannot merge into detached HEAD
 cannotReadBecause=cannot read {0}: {1}
 cannotReadPackageInformation=Cannot read package information.
 cannotRenameDetachedHEAD=Cannot rename detached HEAD
@@ -39,6 +41,7 @@ dateInfo=Date:   {0}
 deletedBranch=Deleted branch {0}
 deletedRemoteBranch=Deleted remote branch {0}
 doesNotExist={0} does not exist
+dontOverwriteLocalChanges=error: Your local changes to the following file would be overwritten by merge:
 everythingUpToDate=Everything up-to-date
 expectedNumberOfbytes=Expected {0} bytes.
 exporting=Exporting {0}
@@ -54,6 +57,9 @@ initializedEmptyGitRepositoryIn=Initialized empty Git repository in {0}
 invalidHttpProxyOnlyHttpSupported=Invalid http_proxy: {0}: Only http supported.
 jgitVersion=jgit version {0}
 listeningOn=Listening on {0}
+mergeConflict=CONFLICT(content): Merge conflict in {0}
+mergeFailed=Automatic merge failed; fix conflicts and then commit the result
+mergeMadeBy=Merge made by {0}
 metaVar_DAG=DAG
 metaVar_KEY=KEY
 metaVar_arg=ARG
@@ -115,6 +121,7 @@ noteObjectTooLargeToPrint=Note object {0} too large to print
 onlyOneMetaVarExpectedIn=Only one {0} expected in {1}.
 pushTo=To {0}
 pathsRequired=at least one path has to be specified when using --only
+refDoesNotExistOrNoCommit={0} does not exist or is not referring to a commit
 remoteMessage=remote: {0}
 remoteRefObjectChangedIsNotExpectedOne=remote ref object changed - is not expected one {0}
 remoteSideDoesNotSupportDeletingRefs=remote side does not support deleting refs
@@ -123,6 +130,7 @@ serviceNotSupported=Service '{0}' not supported
 skippingObject=skipping {0} {1}
 timeInMilliSeconds={0} ms
 tooManyRefsGiven=Too many refs given
+unknownMergeStratey=unknown merge strategy {0} specified
 unsupportedOperation=Unsupported operation: {0}
 usage_CommandLineClientForamazonsS3Service=Command line client for Amazon's S3 service
 usage_CommitAuthor=Override the author name used in the commit. You can use the standard A U Thor <author@example.com> format.
@@ -136,6 +144,7 @@ usage_DisplayTheVersionOfJgit=Display the version of jgit
 usage_IPZillaPassword=IPZilla Password
 usage_IPZillaURL=IPZilla URL
 usage_IPZillausername=IPZilla Username
+usage_MergesTwoDevelopmentHistories=Merges two developement histories
 usage_RepositoryToReadFrom=Repository to read from
 usage_RepositoryToReceiveInto=Repository to receive into
 usage_ServerSideBackendForJgitFetch=Server side backend for 'jgit fetch'
@@ -183,6 +192,7 @@ usage_inputOutputFile=Input/output file
 usage_listBothRemoteTrackingAndLocalBranches=list both remote-tracking and local branches
 usage_listCreateOrDeleteBranches=List, create, or delete branches
 usage_logAllPretty=format:%H %ct %P' output=log --all '--pretty=format:%H %ct %P' output
+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_noPrefix=do not show any source or destination prefix
index c460bc3b4a899d3c97fe8b97add3acf11a561d6f..cf57f20b7ba5d8f48fc0953aa41352b9f1264836 100644 (file)
@@ -73,9 +73,11 @@ public class CLIText extends TranslationBundle {
        /***/ public String cannotCreateCommand;
        /***/ public String cannotCreateOutputStream;
        /***/ public String cannotDeatchHEAD;
+       /***/ public String cannotDeleteFile;
        /***/ public String cannotDeleteTheBranchWhichYouAreCurrentlyOn;
        /***/ public String cannotGuessLocalNameFrom;
        /***/ public String cannotLock;
+       /***/ public String cannotMergeDetachedHead;
        /***/ public String cannotReadBecause;
        /***/ public String cannotReadPackageInformation;
        /***/ public String cannotRenameDetachedHEAD;
@@ -92,6 +94,7 @@ public class CLIText extends TranslationBundle {
        /***/ public String deletedBranch;
        /***/ public String deletedRemoteBranch;
        /***/ public String doesNotExist;
+       /***/ public String dontOverwriteLocalChanges;
        /***/ public String everythingUpToDate;
        /***/ public String expectedNumberOfbytes;
        /***/ public String exporting;
@@ -107,6 +110,9 @@ public class CLIText extends TranslationBundle {
        /***/ public String invalidHttpProxyOnlyHttpSupported;
        /***/ public String jgitVersion;
        /***/ public String listeningOn;
+       /***/ public String mergeConflict;
+       /***/ public String mergeFailed;
+       /***/ public String mergeMadeBy;
        /***/ public String metaVar_command;
        /***/ public String metaVar_commitish;
        /***/ public String metaVar_object;
@@ -134,6 +140,7 @@ public class CLIText extends TranslationBundle {
        /***/ public String onlyOneMetaVarExpectedIn;
        /***/ public String pushTo;
        /***/ public String pathsRequired;
+       /***/ public String refDoesNotExistOrNoCommit;
        /***/ public String remoteMessage;
        /***/ public String remoteRefObjectChangedIsNotExpectedOne;
        /***/ public String remoteSideDoesNotSupportDeletingRefs;
@@ -142,6 +149,7 @@ public class CLIText extends TranslationBundle {
        /***/ public String skippingObject;
        /***/ public String timeInMilliSeconds;
        /***/ public String tooManyRefsGiven;
+       /***/ public String unknownMergeStratey;
        /***/ public String unsupportedOperation;
        /***/ public String warningNoCommitGivenOnCommandLine;
 }
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
new file mode 100644 (file)
index 0000000..73ab2b2
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2011, 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
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.pgm;
+
+import java.text.MessageFormat;
+import java.util.Map;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.MergeResult;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.merge.MergeStrategy;
+import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+@Command(common = true, usage = "usage_MergesTwoDevelopmentHistories")
+class Merge extends TextBuiltin {
+
+       @Option(name = "--strategy", aliases = { "-s" }, usage = "usage_mergeStrategy")
+       private String strategyName;
+
+       private MergeStrategy mergeStrategy = MergeStrategy.RESOLVE;
+
+       @Argument(required = true)
+       private String ref;
+
+       @Override
+       protected void run() throws Exception {
+               // determine the merge strategy
+               if (strategyName != null) {
+                       mergeStrategy = MergeStrategy.get(strategyName);
+                       if (mergeStrategy == null)
+                               throw die(MessageFormat.format(
+                                               CLIText.get().unknownMergeStratey, strategyName));
+               }
+
+               // determine the other revision we want to merge with HEAD
+               final ObjectId src = db.resolve(ref + "^{commit}");
+               if (src == null)
+                       throw die(MessageFormat.format(
+                                       CLIText.get().refDoesNotExistOrNoCommit, ref));
+
+               Git git = new Git(db);
+               MergeResult result = git.merge().setStrategy(mergeStrategy)
+                               .include(src).call();
+
+               switch (result.getMergeStatus()) {
+               case ALREADY_UP_TO_DATE:
+               case FAST_FORWARD:
+                       out.println(result.getMergeStatus().toString());
+                       break;
+               case CONFLICTING:
+                       for (String collidingPath : result.getConflicts().keySet())
+                               out.println(MessageFormat.format(CLIText.get().mergeConflict,
+                                               collidingPath));
+                       out.println(CLIText.get().mergeFailed);
+                       break;
+               case FAILED:
+                       for (Map.Entry<String, MergeFailureReason> entry : result
+                                       .getFailingPaths().entrySet())
+                               switch (entry.getValue()) {
+                               case DIRTY_WORKTREE:
+                               case DIRTY_INDEX:
+                                       out.println(CLIText.get().dontOverwriteLocalChanges);
+                                       out.println("        " + entry.getKey());
+                                       break;
+                               case COULD_NOT_DELETE:
+                                       out.println(CLIText.get().cannotDeleteFile);
+                                       out.println("        " + entry.getKey());
+                                       break;
+                               }
+                       break;
+               case MERGED:
+                       out.println(MessageFormat.format(CLIText.get().mergeMadeBy,
+                                       mergeStrategy.getName()));
+               case NOT_SUPPORTED:
+                       out.println(MessageFormat.format(
+                                       CLIText.get().unsupportedOperation, result.toString()));
+               }
+       }
+}