From b205597b91027bf56ef9e7a6398c3037f662feb2 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Fri, 20 Aug 2010 09:32:07 -0700 Subject: [PATCH] Add a public RevCommit.parse() method Callers might have a canonical commit encoding on hand that they wish to convert into a clean structure for presentation purposes, and the object may not be available in a repository. (E.g. maybe its a "draft" commit being written in an editor.) Change-Id: I21759cff337cbbb34dbdde91aec5aa4448a1ef37 Signed-off-by: Shawn O. Pearce --- .../jgit/revwalk/RevCommitParseTest.java | 21 ++++++++ .../org/eclipse/jgit/revwalk/RevCommit.java | 48 +++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java index b7e84419c..935437337 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java @@ -44,9 +44,12 @@ package org.eclipse.jgit.revwalk; import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; +import org.eclipse.jgit.lib.Commit; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.RepositoryTestCase; @@ -315,6 +318,24 @@ public class RevCommitParseTest extends RepositoryTestCase { assertEquals(shortMsg, c.getShortMessage()); } + public void testParse_PublicParseMethod() + throws UnsupportedEncodingException { + ObjectInserter.Formatter fmt = new ObjectInserter.Formatter(); + Commit src = new Commit(); + src.setTreeId(fmt.idFor(Constants.OBJ_TREE, new byte[] {})); + src.setAuthor(author); + src.setCommitter(committer); + src.setMessage("Test commit\n\nThis is a test.\n"); + + RevCommit p = RevCommit.parse(fmt.format(src)); + assertEquals(src.getTreeId(), p.getTree()); + assertEquals(0, p.getParentCount()); + assertEquals(author, p.getAuthorIdent()); + assertEquals(committer, p.getCommitterIdent()); + assertEquals("Test commit", p.getShortMessage()); + assertEquals(src.getMessage(), p.getFullMessage()); + } + private static ObjectId id(final String str) { return ObjectId.fromString(str); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java index 74a51c8a4..9e018b7a0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java @@ -55,11 +55,59 @@ import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.MutableObjectId; +import org.eclipse.jgit.lib.ObjectInserter; +import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.util.RawParseUtils; /** A commit reference to a commit in the DAG. */ public class RevCommit extends RevObject { + /** + * Parse a commit from its canonical format. + * + * This method constructs a temporary revision pool, parses the commit as + * supplied, and returns it to the caller. Since the commit was built inside + * of a private revision pool its parent pointers will be initialized, but + * will not have their headers loaded. + * + * Applications are discouraged from using this API. Callers usually need + * more than one commit. Use {@link RevWalk#parseCommit(AnyObjectId)} to + * obtain a RevCommit from an existing repository. + * + * @param raw + * the canonical formatted commit to be parsed. + * @return the parsed commit, in an isolated revision pool that is not + * available to the caller. + */ + public static RevCommit parse(byte[] raw) { + return parse(new RevWalk((ObjectReader) null), raw); + } + + /** + * Parse a commit from its canonical format. + * + * This method inserts the commit directly into the caller supplied revision + * pool, making it appear as though the commit exists in the repository, + * even if it doesn't. The repository under the pool is not affected. + * + * @param rw + * the revision pool to allocate the commit within. The commit's + * tree and parent pointers will be obtained from this pool. + * @param raw + * the canonical formatted commit to be parsed. + * @return the parsed commit, in an isolated revision pool that is not + * available to the caller. + */ + public static RevCommit parse(RevWalk rw, byte[] raw) { + ObjectInserter.Formatter fmt = new ObjectInserter.Formatter(); + boolean retain = rw.isRetainBody(); + rw.setRetainBody(true); + RevCommit r = rw.lookupCommit(fmt.idFor(Constants.OBJ_COMMIT, raw)); + r.parseCanonical(rw, raw); + rw.setRetainBody(retain); + return r; + } + static final RevCommit[] NO_PARENTS = {}; private RevTree tree;