summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.junit
diff options
context:
space:
mode:
authorDave Borowitz <dborowitz@google.com>2015-03-18 10:46:41 -0700
committerDave Borowitz <dborowitz@google.com>2015-03-23 13:03:31 -0700
commitf1a15f7eb09183124ea645a8bfc16a03d58fd385 (patch)
tree8583a1146018ef0534912f7709154804f6bb1b54 /org.eclipse.jgit.junit
parentdd453f4185c8e7e9608605a35abd4ac4eaadba76 (diff)
downloadjgit-f1a15f7eb09183124ea645a8bfc16a03d58fd385.tar.gz
jgit-f1a15f7eb09183124ea645a8bfc16a03d58fd385.zip
TestRepository: Add a cherryPick method
CherryPickCommand only works on a non-bare repository, as it must modify the working tree and index in case of a merge conflict. In tests, being able to recover from a merge conflict is less important, as the caller should be able to control the full contents of files in advance of the cherry-pick. Change-Id: Ic332e44df1308b9336e884666b08c1f6db64513d
Diffstat (limited to 'org.eclipse.jgit.junit')
-rw-r--r--org.eclipse.jgit.junit/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java62
2 files changed, 63 insertions, 0 deletions
diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
index b20464e397..327a697f66 100644
--- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
@@ -14,6 +14,7 @@ Import-Package: org.eclipse.jgit.api;version="[4.0.0,4.1.0)",
org.eclipse.jgit.internal.storage.file;version="[4.0.0,4.1.0)",
org.eclipse.jgit.internal.storage.pack;version="[4.0.0,4.1.0)",
org.eclipse.jgit.lib;version="[4.0.0,4.1.0)",
+ org.eclipse.jgit.merge;version="[4.0.0,4.1.0)",
org.eclipse.jgit.revwalk;version="[4.0.0,4.1.0)",
org.eclipse.jgit.storage.file;version="[4.0.0,4.1.0)",
org.eclipse.jgit.treewalk;version="[4.0.0,4.1.0)",
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
index ce33ec7094..925a6b0216 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
@@ -52,11 +52,13 @@ import java.io.IOException;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.TimeZone;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.dircache.DirCache;
@@ -88,6 +90,8 @@ import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefWriter;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.TagBuilder;
+import org.eclipse.jgit.merge.MergeStrategy;
+import org.eclipse.jgit.merge.ThreeWayMerger;
import org.eclipse.jgit.revwalk.ObjectWalk;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -187,6 +191,11 @@ public class TestRepository<R extends Repository> {
return new Date(now);
}
+ /** @return timezone used for default identities. */
+ public TimeZone getTimeZone() {
+ return defaultCommitter.getTimeZone();
+ }
+
/**
* Adjust the current time that will used by the next commit.
*
@@ -616,6 +625,59 @@ public class TestRepository<R extends Repository> {
}
/**
+ * Cherry-pick a commit onto HEAD.
+ * <p>
+ * This differs from {@code git cherry-pick} in that it works in a bare
+ * repository. As a result, any merge failure results in an exception, as
+ * there is no way to recover.
+ *
+ * @param id
+ * commit-ish to cherry-pick.
+ * @return newly created commit, or null if no work was done due to the
+ * resulting tree being identical.
+ * @throws Exception
+ */
+ public RevCommit cherryPick(AnyObjectId id) throws Exception {
+ RevCommit commit = pool.parseCommit(id);
+ pool.parseBody(commit);
+ if (commit.getParentCount() != 1)
+ throw new IOException(String.format(
+ "Expected 1 parent for %s, found: %s",
+ id.name(), Arrays.asList(commit.getParents())));
+ RevCommit parent = commit.getParent(0);
+ pool.parseHeaders(parent);
+
+ Ref headRef = db.getRef(Constants.HEAD);
+ if (headRef == null)
+ throw new IOException("Missing HEAD");
+ RevCommit head = pool.parseCommit(headRef.getObjectId());
+
+ ThreeWayMerger merger = MergeStrategy.RECURSIVE.newMerger(db, true);
+ merger.setBase(parent.getTree());
+ if (merger.merge(head, commit)) {
+ if (AnyObjectId.equals(head.getTree(), merger.getResultTreeId()))
+ return null;
+ tick(1);
+ org.eclipse.jgit.lib.CommitBuilder b =
+ new org.eclipse.jgit.lib.CommitBuilder();
+ b.setParentId(head);
+ b.setTreeId(merger.getResultTreeId());
+ b.setAuthor(commit.getAuthorIdent());
+ b.setCommitter(new PersonIdent(defaultCommitter, new Date(now)));
+ b.setMessage(commit.getFullMessage());
+ ObjectId result;
+ try (ObjectInserter ins = inserter) {
+ result = ins.insert(b);
+ ins.flush();
+ }
+ update(Constants.HEAD, result);
+ return pool.parseCommit(result);
+ } else {
+ throw new IOException("Merge conflict");
+ }
+ }
+
+ /**
* Update the dumb client server info files.
*
* @throws Exception