diff options
author | Dave Borowitz <dborowitz@google.com> | 2015-03-18 10:46:41 -0700 |
---|---|---|
committer | Dave Borowitz <dborowitz@google.com> | 2015-03-23 13:03:31 -0700 |
commit | f1a15f7eb09183124ea645a8bfc16a03d58fd385 (patch) | |
tree | 8583a1146018ef0534912f7709154804f6bb1b54 /org.eclipse.jgit.junit | |
parent | dd453f4185c8e7e9608605a35abd4ac4eaadba76 (diff) | |
download | jgit-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.MF | 1 | ||||
-rw-r--r-- | org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java | 62 |
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 |