Make Commit class only for writing

The Commit class now only supports the creation of a commit object.
To read a commit, applictions should use RevCommit.  This permits
us to have exactly one implementation, and RevCommit's is faster
and more bug-free.

Change-Id: Ib573f7e15f36855112815269385c21dea532e2cf
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
Shawn O. Pearce 2010-08-20 08:53:46 -07:00
parent cf9537c8ce
commit b46b635c03
15 changed files with 387 additions and 463 deletions

View File

@ -359,7 +359,7 @@ public RevCommit commit(final int secDelta, final RevTree tree,
final RevCommit... parents) throws Exception { final RevCommit... parents) throws Exception {
tick(secDelta); tick(secDelta);
final Commit c = new Commit(db); final Commit c = new Commit();
c.setTreeId(tree); c.setTreeId(tree);
c.setParentIds(parents); c.setParentIds(parents);
c.setAuthor(new PersonIdent(author, new Date(now))); c.setAuthor(new PersonIdent(author, new Date(now)));
@ -811,8 +811,8 @@ public RevCommit create() throws Exception {
if (self == null) { if (self == null) {
TestRepository.this.tick(tick); TestRepository.this.tick(tick);
final Commit c = new Commit(db); final Commit c = new Commit();
c.setParentIds(parents.toArray(new RevCommit[parents.size()])); c.setParentIds(parents);
c.setAuthor(new PersonIdent(author, new Date(now))); c.setAuthor(new PersonIdent(author, new Date(now)));
c.setCommitter(new PersonIdent(committer, new Date(now))); c.setCommitter(new PersonIdent(committer, new Date(now)));
c.setMessage(message); c.setMessage(message);

View File

@ -51,11 +51,10 @@
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.kohsuke.args4j.Argument; import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.kohsuke.args4j.Option; import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.NotSupportedException;
import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.lib.Commit;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.GitIndex; import org.eclipse.jgit.lib.GitIndex;
import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Ref;
@ -64,12 +63,16 @@
import org.eclipse.jgit.lib.TextProgressMonitor; import org.eclipse.jgit.lib.TextProgressMonitor;
import org.eclipse.jgit.lib.Tree; import org.eclipse.jgit.lib.Tree;
import org.eclipse.jgit.lib.WorkDirCheckout; import org.eclipse.jgit.lib.WorkDirCheckout;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.storage.file.FileRepository; import org.eclipse.jgit.storage.file.FileRepository;
import org.eclipse.jgit.transport.FetchResult; import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.Transport;
import org.eclipse.jgit.transport.URIish; import org.eclipse.jgit.transport.URIish;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@Command(common = true, usage = "usage_cloneRepositoryIntoNewDir") @Command(common = true, usage = "usage_cloneRepositoryIntoNewDir")
class Clone extends AbstractFetchCommand { class Clone extends AbstractFetchCommand {
@ -174,17 +177,30 @@ private void doCheckout(final Ref branch) throws IOException {
u.link(branch.getName()); u.link(branch.getName());
} }
final Commit commit = db.mapCommit(branch.getObjectId()); final RevCommit commit = parseCommit(branch);
final RefUpdate u = db.updateRef(Constants.HEAD); final RefUpdate u = db.updateRef(Constants.HEAD);
u.setNewObjectId(commit.getCommitId()); u.setNewObjectId(commit);
u.forceUpdate(); u.forceUpdate();
final GitIndex index = new GitIndex(db); final GitIndex index = new GitIndex(db);
final Tree tree = commit.getTree(); final Tree tree = db.mapTree(commit.getTree());
final WorkDirCheckout co; final WorkDirCheckout co;
co = new WorkDirCheckout(db, db.getWorkTree(), index, tree); co = new WorkDirCheckout(db, db.getWorkTree(), index, tree);
co.checkout(); co.checkout();
index.write(); index.write();
} }
private RevCommit parseCommit(final Ref branch)
throws MissingObjectException, IncorrectObjectTypeException,
IOException {
final RevWalk rw = new RevWalk(db);
final RevCommit commit;
try {
commit = rw.parseCommit(branch.getObjectId());
} finally {
rw.release();
}
return commit;
}
} }

View File

@ -56,26 +56,25 @@
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.ObjectWritingException; import org.eclipse.jgit.errors.ObjectWritingException;
import org.eclipse.jgit.lib.Commit; import org.eclipse.jgit.lib.Commit;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdRef; import org.eclipse.jgit.lib.ObjectIdRef;
import org.eclipse.jgit.lib.ObjectWriter; import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefWriter; import org.eclipse.jgit.lib.RefWriter;
import org.eclipse.jgit.lib.TextProgressMonitor; import org.eclipse.jgit.lib.TextProgressMonitor;
import org.eclipse.jgit.lib.Tree;
import org.eclipse.jgit.pgm.CLIText; import org.eclipse.jgit.pgm.CLIText;
import org.eclipse.jgit.pgm.TextBuiltin; import org.eclipse.jgit.pgm.TextBuiltin;
import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.storage.file.LockFile; import org.eclipse.jgit.storage.file.LockFile;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
/** /**
* Recreates a repository from another one's commit graph. * Recreates a repository from another one's commit graph.
@ -164,8 +163,8 @@ private void recreateCommitGraph() throws IOException {
} }
pm.beginTask("Rewriting commits", queue.size()); pm.beginTask("Rewriting commits", queue.size());
final ObjectWriter ow = new ObjectWriter(db); final ObjectInserter oi = db.newObjectInserter();
final ObjectId emptyTree = ow.writeTree(new Tree(db)); final ObjectId emptyTree = oi.insert(Constants.OBJ_TREE, new byte[] {});
final PersonIdent me = new PersonIdent("jgit rebuild-commitgraph", final PersonIdent me = new PersonIdent("jgit rebuild-commitgraph",
"rebuild-commitgraph@localhost"); "rebuild-commitgraph@localhost");
while (!queue.isEmpty()) { while (!queue.isEmpty()) {
@ -192,17 +191,19 @@ private void recreateCommitGraph() throws IOException {
} }
} }
final Commit newc = new Commit(db); final Commit newc = new Commit();
newc.setTreeId(emptyTree); newc.setTreeId(emptyTree);
newc.setAuthor(new PersonIdent(me, new Date(t.commitTime))); newc.setAuthor(new PersonIdent(me, new Date(t.commitTime)));
newc.setCommitter(newc.getAuthor()); newc.setCommitter(newc.getAuthor());
newc.setParentIds(newParents); newc.setParentIds(newParents);
newc.setMessage("ORIGINAL " + t.oldId.name() + "\n"); newc.setMessage("ORIGINAL " + t.oldId.name() + "\n");
t.newId = ow.writeCommit(newc); t.newId = oi.insert(Constants.OBJ_COMMIT,oi.format(newc));
rewrites.put(t.oldId, t.newId); rewrites.put(t.oldId, t.newId);
pm.update(1); pm.update(1);
} }
} }
oi.flush();
oi.release();
pm.endTask(); pm.endTask();
} }

View File

@ -155,8 +155,8 @@ private void checkoutBranch(String branchName) throws Exception {
File workDir = db.getWorkTree(); File workDir = db.getWorkTree();
if (workDir != null) { if (workDir != null) {
WorkDirCheckout workDirCheckout = new WorkDirCheckout(db, WorkDirCheckout workDirCheckout = new WorkDirCheckout(db,
workDir, db.mapCommit(Constants.HEAD).getTree(), workDir, db.mapTree(Constants.HEAD),
db.getIndex(), db.mapCommit(branchName).getTree()); db.getIndex(), db.mapTree(branchName));
workDirCheckout.setFailOnConflict(true); workDirCheckout.setFailOnConflict(true);
try { try {
workDirCheckout.checkout(); workDirCheckout.checkout();

View File

@ -104,11 +104,11 @@ private void addFileToTree(final Tree t, String filename, String content)
private void commit(final Tree t, String commitMsg, PersonIdent author, private void commit(final Tree t, String commitMsg, PersonIdent author,
PersonIdent committer) throws IOException { PersonIdent committer) throws IOException {
final Commit commit = new Commit(db); final Commit commit = new Commit();
commit.setAuthor(author); commit.setAuthor(author);
commit.setCommitter(committer); commit.setCommitter(committer);
commit.setMessage(commitMsg); commit.setMessage(commitMsg);
commit.setTree(t); commit.setTreeId(t.getTreeId());
ObjectWriter writer = new ObjectWriter(db); ObjectWriter writer = new ObjectWriter(db);
commit.setCommitId(writer.writeCommit(commit)); commit.setCommitId(writer.writeCommit(commit));

View File

@ -131,7 +131,7 @@ private void assertCorrectId(final DirCache treeT, final TreeWalk tw) {
private ObjectId commit(final ObjectInserter odi, final DirCache treeB, private ObjectId commit(final ObjectInserter odi, final DirCache treeB,
final ObjectId[] parentIds) throws Exception { final ObjectId[] parentIds) throws Exception {
final Commit c = new Commit(db); final Commit c = new Commit();
c.setTreeId(treeB.writeTree(odi)); c.setTreeId(treeB.writeTree(odi));
c.setAuthor(new PersonIdent("A U Thor", "a.u.thor", 1L, 0)); c.setAuthor(new PersonIdent("A U Thor", "a.u.thor", 1L, 0));
c.setCommitter(c.getAuthor()); c.setCommitter(c.getAuthor());

View File

@ -367,7 +367,7 @@ private void assertCorrectId(final DirCache treeT, final TreeWalk tw) {
private ObjectId commit(final ObjectInserter odi, final DirCache treeB, private ObjectId commit(final ObjectInserter odi, final DirCache treeB,
final ObjectId[] parentIds) throws Exception { final ObjectId[] parentIds) throws Exception {
final Commit c = new Commit(db); final Commit c = new Commit();
c.setTreeId(treeB.writeTree(odi)); c.setTreeId(treeB.writeTree(odi));
c.setAuthor(new PersonIdent("A U Thor", "a.u.thor", 1L, 0)); c.setAuthor(new PersonIdent("A U Thor", "a.u.thor", 1L, 0));
c.setCommitter(c.getAuthor()); c.setCommitter(c.getAuthor());

View File

@ -53,15 +53,20 @@
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import org.eclipse.jgit.JGitText; import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Commit; import org.eclipse.jgit.lib.Commit;
import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileTreeEntry; import org.eclipse.jgit.lib.FileTreeEntry;
import org.eclipse.jgit.lib.ObjectDatabase; import org.eclipse.jgit.lib.ObjectDatabase;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.ObjectWriter; import org.eclipse.jgit.lib.ObjectWriter;
import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.RefUpdate;
@ -71,6 +76,8 @@
import org.eclipse.jgit.lib.Tree; import org.eclipse.jgit.lib.Tree;
import org.eclipse.jgit.lib.TreeEntry; import org.eclipse.jgit.lib.TreeEntry;
import org.eclipse.jgit.lib.WriteTree; import org.eclipse.jgit.lib.WriteTree;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
public class T0003_Basic extends SampleDataRepositoryTestCase { public class T0003_Basic extends SampleDataRepositoryTestCase {
public void test001_Initalize() { public void test001_Initalize() {
@ -243,7 +250,8 @@ public void test000_openrepo_alternate_index_file_and_objdirs()
assertEqualsPath(theDir.getParentFile(), r.getWorkTree()); assertEqualsPath(theDir.getParentFile(), r.getWorkTree());
assertEqualsPath(indexFile, r.getIndexFile()); assertEqualsPath(indexFile, r.getIndexFile());
assertEqualsPath(objDir, r.getObjectDatabase().getDirectory()); assertEqualsPath(objDir, r.getObjectDatabase().getDirectory());
assertNotNull(r.mapCommit("6db9c2ebf75590eef973081736730a9ea169a0c4")); assertNotNull(r.open(ObjectId
.fromString("6db9c2ebf75590eef973081736730a9ea169a0c4")));
// Must close or the default repo pack files created by this test gets // Must close or the default repo pack files created by this test gets
// locked via the alternate object directories on Windows. // locked via the alternate object directories on Windows.
r.close(); r.close();
@ -374,13 +382,15 @@ public void test009_CreateCommitOldFormat() throws IOException {
assertEquals(ObjectId.fromString("00b1f73724f493096d1ffa0b0f1f1482dbb8c936"), assertEquals(ObjectId.fromString("00b1f73724f493096d1ffa0b0f1f1482dbb8c936"),
t.getTreeId()); t.getTreeId());
final Commit c = new Commit(db); final Commit c = new Commit();
c.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60)); c.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60));
c.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60)); c.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60));
c.setMessage("A Commit\n"); c.setMessage("A Commit\n");
c.setTree(t); c.setTreeId(t.getTreeId());
assertEquals(t.getTreeId(), c.getTreeId()); assertEquals(t.getTreeId(), c.getTreeId());
c.commit();
insertCommit(c);
final ObjectId cmtid = ObjectId.fromString( final ObjectId cmtid = ObjectId.fromString(
"803aec4aba175e8ab1d666873c984c0308179099"); "803aec4aba175e8ab1d666873c984c0308179099");
assertEquals(cmtid, c.getCommitId()); assertEquals(cmtid, c.getCommitId());
@ -399,12 +409,12 @@ public void test009_CreateCommitOldFormat() throws IOException {
} }
// Verify we can read it. // Verify we can read it.
final Commit c2 = db.mapCommit(cmtid); RevCommit c2 = parseCommit(c.getCommitId());
assertNotNull(c2); assertNotNull(c2);
assertEquals(c.getMessage(), c2.getMessage()); assertEquals(c.getMessage(), c2.getFullMessage());
assertEquals(c.getTreeId(), c2.getTreeId()); assertEquals(c.getTreeId(), c2.getTree());
assertEquals(c.getAuthor(), c2.getAuthor()); assertEquals(c.getAuthor(), c2.getAuthorIdent());
assertEquals(c.getCommitter(), c2.getCommitter()); assertEquals(c.getCommitter(), c2.getCommitterIdent());
} }
public void test012_SubtreeExternalSorting() throws IOException { public void test012_SubtreeExternalSorting() throws IOException {
@ -484,12 +494,12 @@ public void test022_createCommitTag() throws IOException {
final Tree almostEmptyTree = new Tree(db); final Tree almostEmptyTree = new Tree(db);
almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId, "empty".getBytes(), false)); almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId, "empty".getBytes(), false));
final ObjectId almostEmptyTreeId = new ObjectWriter(db).writeTree(almostEmptyTree); final ObjectId almostEmptyTreeId = new ObjectWriter(db).writeTree(almostEmptyTree);
final Commit almostEmptyCommit = new Commit(db); final Commit almostEmptyCommit = new Commit();
almostEmptyCommit.setAuthor(new PersonIdent(author, 1154236443000L, -2 * 60)); // not exactly the same almostEmptyCommit.setAuthor(new PersonIdent(author, 1154236443000L, -2 * 60)); // not exactly the same
almostEmptyCommit.setCommitter(new PersonIdent(author, 1154236443000L, -2 * 60)); almostEmptyCommit.setCommitter(new PersonIdent(author, 1154236443000L, -2 * 60));
almostEmptyCommit.setMessage("test022\n"); almostEmptyCommit.setMessage("test022\n");
almostEmptyCommit.setTreeId(almostEmptyTreeId); almostEmptyCommit.setTreeId(almostEmptyTreeId);
ObjectId almostEmptyCommitId = new ObjectWriter(db).writeCommit(almostEmptyCommit); ObjectId almostEmptyCommitId = insertCommit(almostEmptyCommit);
final Tag t = new Tag(db); final Tag t = new Tag(db);
t.setObjId(almostEmptyCommitId); t.setObjId(almostEmptyCommitId);
t.setType("commit"); t.setType("commit");
@ -511,17 +521,17 @@ public void test023_createCommitNonAnullii() throws IOException {
final Tree almostEmptyTree = new Tree(db); final Tree almostEmptyTree = new Tree(db);
almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId, "empty".getBytes(), false)); almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId, "empty".getBytes(), false));
final ObjectId almostEmptyTreeId = new ObjectWriter(db).writeTree(almostEmptyTree); final ObjectId almostEmptyTreeId = new ObjectWriter(db).writeTree(almostEmptyTree);
Commit commit = new Commit(db); Commit commit = new Commit();
commit.setTreeId(almostEmptyTreeId); commit.setTreeId(almostEmptyTreeId);
commit.setAuthor(new PersonIdent("Joe H\u00e4cker","joe@example.com",4294967295000L,60)); commit.setAuthor(new PersonIdent("Joe H\u00e4cker","joe@example.com",4294967295000L,60));
commit.setCommitter(new PersonIdent("Joe Hacker","joe2@example.com",4294967295000L,60)); commit.setCommitter(new PersonIdent("Joe Hacker","joe2@example.com",4294967295000L,60));
commit.setEncoding("UTF-8"); commit.setEncoding("UTF-8");
commit.setMessage("\u00dcbergeeks"); commit.setMessage("\u00dcbergeeks");
ObjectId cid = new ObjectWriter(db).writeCommit(commit); ObjectId cid = insertCommit(commit);
assertEquals("4680908112778718f37e686cbebcc912730b3154", cid.name()); assertEquals("4680908112778718f37e686cbebcc912730b3154", cid.name());
Commit loadedCommit = db.mapCommit(cid);
assertNotSame(loadedCommit, commit); RevCommit loadedCommit = parseCommit(cid);
assertEquals(commit.getMessage(), loadedCommit.getMessage()); assertEquals(commit.getMessage(), loadedCommit.getFullMessage());
} }
public void test024_createCommitNonAscii() throws IOException { public void test024_createCommitNonAscii() throws IOException {
@ -529,13 +539,13 @@ public void test024_createCommitNonAscii() throws IOException {
final Tree almostEmptyTree = new Tree(db); final Tree almostEmptyTree = new Tree(db);
almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId, "empty".getBytes(), false)); almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId, "empty".getBytes(), false));
final ObjectId almostEmptyTreeId = new ObjectWriter(db).writeTree(almostEmptyTree); final ObjectId almostEmptyTreeId = new ObjectWriter(db).writeTree(almostEmptyTree);
Commit commit = new Commit(db); Commit commit = new Commit();
commit.setTreeId(almostEmptyTreeId); commit.setTreeId(almostEmptyTreeId);
commit.setAuthor(new PersonIdent("Joe H\u00e4cker","joe@example.com",4294967295000L,60)); commit.setAuthor(new PersonIdent("Joe H\u00e4cker","joe@example.com",4294967295000L,60));
commit.setCommitter(new PersonIdent("Joe Hacker","joe2@example.com",4294967295000L,60)); commit.setCommitter(new PersonIdent("Joe Hacker","joe2@example.com",4294967295000L,60));
commit.setEncoding("ISO-8859-1"); commit.setEncoding("ISO-8859-1");
commit.setMessage("\u00dcbergeeks"); commit.setMessage("\u00dcbergeeks");
ObjectId cid = new ObjectWriter(db).writeCommit(commit); ObjectId cid = insertCommit(commit);
assertEquals("2979b39d385014b33287054b87f77bcb3ecb5ebf", cid.name()); assertEquals("2979b39d385014b33287054b87f77bcb3ecb5ebf", cid.name());
} }
@ -601,82 +611,82 @@ public void test026_CreateCommitMultipleparents() throws IOException {
assertEquals(ObjectId.fromString("00b1f73724f493096d1ffa0b0f1f1482dbb8c936"), assertEquals(ObjectId.fromString("00b1f73724f493096d1ffa0b0f1f1482dbb8c936"),
t.getTreeId()); t.getTreeId());
final Commit c1 = new Commit(db); final Commit c1 = new Commit();
c1.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60)); c1.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60));
c1.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60)); c1.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60));
c1.setMessage("A Commit\n"); c1.setMessage("A Commit\n");
c1.setTree(t); c1.setTreeId(t.getTreeId());
assertEquals(t.getTreeId(), c1.getTreeId()); assertEquals(t.getTreeId(), c1.getTreeId());
c1.commit(); insertCommit(c1);
final ObjectId cmtid1 = ObjectId.fromString( final ObjectId cmtid1 = ObjectId.fromString(
"803aec4aba175e8ab1d666873c984c0308179099"); "803aec4aba175e8ab1d666873c984c0308179099");
assertEquals(cmtid1, c1.getCommitId()); assertEquals(cmtid1, c1.getCommitId());
final Commit c2 = new Commit(db); final Commit c2 = new Commit();
c2.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60)); c2.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60));
c2.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60)); c2.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60));
c2.setMessage("A Commit 2\n"); c2.setMessage("A Commit 2\n");
c2.setTree(t); c2.setTreeId(t.getTreeId());
assertEquals(t.getTreeId(), c2.getTreeId()); assertEquals(t.getTreeId(), c2.getTreeId());
c2.setParentIds(new ObjectId[] { c1.getCommitId() } ); c2.setParentIds(c1.getCommitId());
c2.commit(); insertCommit(c2);
final ObjectId cmtid2 = ObjectId.fromString( final ObjectId cmtid2 = ObjectId.fromString(
"95d068687c91c5c044fb8c77c5154d5247901553"); "95d068687c91c5c044fb8c77c5154d5247901553");
assertEquals(cmtid2, c2.getCommitId()); assertEquals(cmtid2, c2.getCommitId());
Commit rm2 = db.mapCommit(cmtid2); RevCommit rm2 = parseCommit(cmtid2);
assertNotSame(c2, rm2); // assert the parsed objects is not from the cache assertNotSame(c2, rm2); // assert the parsed objects is not from the cache
assertEquals(c2.getAuthor(), rm2.getAuthor()); assertEquals(c2.getAuthor(), rm2.getAuthorIdent());
assertEquals(c2.getCommitId(), rm2.getCommitId()); assertEquals(c2.getCommitId(), rm2.getId());
assertEquals(c2.getMessage(), rm2.getMessage()); assertEquals(c2.getMessage(), rm2.getFullMessage());
assertEquals(c2.getTree().getTreeId(), rm2.getTree().getTreeId()); assertEquals(c2.getTreeId(), rm2.getTree().getId());
assertEquals(1, rm2.getParentIds().length); assertEquals(1, rm2.getParentCount());
assertEquals(c1.getCommitId(), rm2.getParentIds()[0]); assertEquals(c1.getCommitId(), rm2.getParent(0));
final Commit c3 = new Commit(db); final Commit c3 = new Commit();
c3.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60)); c3.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60));
c3.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60)); c3.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60));
c3.setMessage("A Commit 3\n"); c3.setMessage("A Commit 3\n");
c3.setTree(t); c3.setTreeId(t.getTreeId());
assertEquals(t.getTreeId(), c3.getTreeId()); assertEquals(t.getTreeId(), c3.getTreeId());
c3.setParentIds(new ObjectId[] { c1.getCommitId(), c2.getCommitId() }); c3.setParentIds(c1.getCommitId(), c2.getCommitId());
c3.commit(); insertCommit(c3);
final ObjectId cmtid3 = ObjectId.fromString( final ObjectId cmtid3 = ObjectId.fromString(
"ce6e1ce48fbeeb15a83f628dc8dc2debefa066f4"); "ce6e1ce48fbeeb15a83f628dc8dc2debefa066f4");
assertEquals(cmtid3, c3.getCommitId()); assertEquals(cmtid3, c3.getCommitId());
Commit rm3 = db.mapCommit(cmtid3); RevCommit rm3 = parseCommit(cmtid3);
assertNotSame(c3, rm3); // assert the parsed objects is not from the cache assertNotSame(c3, rm3); // assert the parsed objects is not from the cache
assertEquals(c3.getAuthor(), rm3.getAuthor()); assertEquals(c3.getAuthor(), rm3.getAuthorIdent());
assertEquals(c3.getCommitId(), rm3.getCommitId()); assertEquals(c3.getCommitId(), rm3.getId());
assertEquals(c3.getMessage(), rm3.getMessage()); assertEquals(c3.getMessage(), rm3.getFullMessage());
assertEquals(c3.getTree().getTreeId(), rm3.getTree().getTreeId()); assertEquals(c3.getTreeId(), rm3.getTree().getId());
assertEquals(2, rm3.getParentIds().length); assertEquals(2, rm3.getParentCount());
assertEquals(c1.getCommitId(), rm3.getParentIds()[0]); assertEquals(c1.getCommitId(), rm3.getParent(0));
assertEquals(c2.getCommitId(), rm3.getParentIds()[1]); assertEquals(c2.getCommitId(), rm3.getParent(1));
final Commit c4 = new Commit(db); final Commit c4 = new Commit();
c4.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60)); c4.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60));
c4.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60)); c4.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60));
c4.setMessage("A Commit 4\n"); c4.setMessage("A Commit 4\n");
c4.setTree(t); c4.setTreeId(t.getTreeId());
assertEquals(t.getTreeId(), c3.getTreeId()); assertEquals(t.getTreeId(), c3.getTreeId());
c4.setParentIds(new ObjectId[] { c1.getCommitId(), c2.getCommitId(), c3.getCommitId() }); c4.setParentIds(c1.getCommitId(), c2.getCommitId(), c3.getCommitId());
c4.commit(); insertCommit(c4);
final ObjectId cmtid4 = ObjectId.fromString( final ObjectId cmtid4 = ObjectId.fromString(
"d1fca9fe3fef54e5212eb67902c8ed3e79736e27"); "d1fca9fe3fef54e5212eb67902c8ed3e79736e27");
assertEquals(cmtid4, c4.getCommitId()); assertEquals(cmtid4, c4.getCommitId());
Commit rm4 = db.mapCommit(cmtid4); RevCommit rm4 = parseCommit(cmtid4);
assertNotSame(c4, rm3); // assert the parsed objects is not from the cache assertNotSame(c4, rm3); // assert the parsed objects is not from the cache
assertEquals(c4.getAuthor(), rm4.getAuthor()); assertEquals(c4.getAuthor(), rm4.getAuthorIdent());
assertEquals(c4.getCommitId(), rm4.getCommitId()); assertEquals(c4.getCommitId(), rm4.getId());
assertEquals(c4.getMessage(), rm4.getMessage()); assertEquals(c4.getMessage(), rm4.getFullMessage());
assertEquals(c4.getTree().getTreeId(), rm4.getTree().getTreeId()); assertEquals(c4.getTreeId(), rm4.getTree().getId());
assertEquals(3, rm4.getParentIds().length); assertEquals(3, rm4.getParentCount());
assertEquals(c1.getCommitId(), rm4.getParentIds()[0]); assertEquals(c1.getCommitId(), rm4.getParent(0));
assertEquals(c2.getCommitId(), rm4.getParentIds()[1]); assertEquals(c2.getCommitId(), rm4.getParent(1));
assertEquals(c3.getCommitId(), rm4.getParentIds()[2]); assertEquals(c3.getCommitId(), rm4.getParent(2));
} }
public void test027_UnpackedRefHigherPriorityThanPacked() throws IOException { public void test027_UnpackedRefHigherPriorityThanPacked() throws IOException {
@ -717,13 +727,6 @@ public void test028_LockPackedRef() throws IOException {
assertEquals(newId2, db.resolve("refs/heads/foobar")); assertEquals(newId2, db.resolve("refs/heads/foobar"));
} }
public void test029_mapObject() throws IOException {
assertEquals(new byte[0].getClass(), db.mapObject(ObjectId.fromString("5b6e7c66c276e7610d4a73c70ec1a1f7c1003259"), null).getClass());
assertEquals(Commit.class, db.mapObject(ObjectId.fromString("540a36d136cf413e4b064c2b0e0a4db60f77feab"), null).getClass());
assertEquals(Tree.class, db.mapObject(ObjectId.fromString("aabf2ffaec9b497f0950352b3e582d73035c2035"), null).getClass());
assertEquals(Tag.class, db.mapObject(ObjectId.fromString("17768080a2318cd89bba4c8b87834401e2095703"), null).getClass());
}
public void test30_stripWorkDir() { public void test30_stripWorkDir() {
File relCwd = new File("."); File relCwd = new File(".");
File absCwd = relCwd.getAbsoluteFile(); File absCwd = relCwd.getAbsoluteFile();
@ -750,6 +753,30 @@ public void test30_stripWorkDir() {
} }
private ObjectId insertCommit(final Commit commit) throws IOException,
UnsupportedEncodingException {
ObjectInserter oi = db.newObjectInserter();
try {
ObjectId id = oi.insert(Constants.OBJ_COMMIT, oi.format(commit));
oi.flush();
commit.setCommitId(id);
return id;
} finally {
oi.release();
}
}
private RevCommit parseCommit(AnyObjectId id)
throws MissingObjectException, IncorrectObjectTypeException,
IOException {
RevWalk rw = new RevWalk(db);
try {
return rw.parseCommit(id);
} finally {
rw.release();
}
}
/** /**
* Kick the timestamp of a local file. * Kick the timestamp of a local file.
* <p> * <p>

View File

@ -162,12 +162,12 @@ public RevCommit call() throws NoHeadException, NoMessageException,
ObjectId indexTreeId = index.writeTree(odi); ObjectId indexTreeId = index.writeTree(odi);
// Create a Commit object, populate it and write it // Create a Commit object, populate it and write it
Commit commit = new Commit(repo); Commit commit = new Commit();
commit.setCommitter(committer); commit.setCommitter(committer);
commit.setAuthor(author); commit.setAuthor(author);
commit.setMessage(message); commit.setMessage(message);
commit.setParentIds(parents.toArray(new ObjectId[] {})); commit.setParentIds(parents);
commit.setTreeId(indexTreeId); commit.setTreeId(indexTreeId);
ObjectId commitId = odi.insert(Constants.OBJ_COMMIT, odi ObjectId commitId = odi.insert(Constants.OBJ_COMMIT, odi
.format(commit)); .format(commit));

View File

@ -57,11 +57,11 @@
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdRef; import org.eclipse.jgit.lib.ObjectIdRef;
import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Ref.Storage;
import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.WorkDirCheckout; import org.eclipse.jgit.lib.WorkDirCheckout;
import org.eclipse.jgit.lib.Ref.Storage;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.merge.MergeStrategy;
import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.revwalk.RevWalk;
@ -176,8 +176,8 @@ private void checkoutNewHead(RevWalk revWalk, RevCommit headCommit,
File workDir = repo.getWorkTree(); File workDir = repo.getWorkTree();
if (workDir != null) { if (workDir != null) {
WorkDirCheckout workDirCheckout = new WorkDirCheckout(repo, WorkDirCheckout workDirCheckout = new WorkDirCheckout(repo,
workDir, headCommit.asCommit(revWalk).getTree(), index, workDir, repo.mapTree(headCommit.getTree()), index,
newHeadCommit.asCommit(revWalk).getTree()); repo.mapTree(newHeadCommit.getTree()));
workDirCheckout.setFailOnConflict(true); workDirCheckout.setFailOnConflict(true);
try { try {
workDirCheckout.checkout(); workDirCheckout.checkout();

View File

@ -51,15 +51,24 @@
import org.eclipse.jgit.JGitText; import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils; import org.eclipse.jgit.util.RawParseUtils;
/** /**
* The configuration file based on the blobs stored in the repository * Configuration file based on the blobs stored in the repository.
*
* This implementation currently only provides reading support, and is primarily
* useful for supporting the {@code .gitmodules} file.
*/ */
public class BlobBasedConfig extends Config { public class BlobBasedConfig extends Config {
/** /**
* The constructor from a byte array * Parse a configuration from a byte array.
* *
* @param base * @param base
* the base configuration file * the base configuration file
@ -75,11 +84,11 @@ public BlobBasedConfig(Config base, final byte[] blob)
} }
/** /**
* The constructor from object identifier * Load a configuration file from a blob.
* *
* @param base * @param base
* the base configuration file * the base configuration file
* @param r * @param db
* the repository * the repository
* @param objectId * @param objectId
* the object identifier * the object identifier
@ -88,22 +97,50 @@ public BlobBasedConfig(Config base, final byte[] blob)
* @throws ConfigInvalidException * @throws ConfigInvalidException
* the blob is not a valid configuration format. * the blob is not a valid configuration format.
*/ */
public BlobBasedConfig(Config base, final Repository r, public BlobBasedConfig(Config base, Repository db, AnyObjectId objectId)
final ObjectId objectId) throws IOException, ConfigInvalidException { throws IOException, ConfigInvalidException {
super(base); this(base, read(db, objectId));
ObjectLoader loader = r.open(objectId, Constants.OBJ_BLOB); }
fromText(RawParseUtils.decode(loader.getCachedBytes()));
private static byte[] read(Repository db, AnyObjectId blobId)
throws MissingObjectException, IncorrectObjectTypeException,
IOException {
ObjectReader or = db.newObjectReader();
try {
return read(or, blobId);
} finally {
or.release();
}
}
private static byte[] read(ObjectReader or, AnyObjectId blobId)
throws MissingObjectException, IncorrectObjectTypeException,
IOException {
ObjectLoader loader = or.open(blobId, Constants.OBJ_BLOB);
if (loader.isLarge()) {
ObjectStream in = loader.openStream();
try {
byte[] buf = new byte[(int) in.getSize()];
IO.readFully(in, buf, 0, buf.length);
return buf;
} finally {
in.close();
}
}
return loader.getCachedBytes();
} }
/** /**
* The constructor from commit and path * Load a configuration file from a blob stored in a specific commit.
* *
* @param base * @param base
* the base configuration file * the base configuration file
* @param commit * @param db
* the commit that contains the object * the repository containing the objects.
* @param treeish
* the tree (or commit) that contains the object
* @param path * @param path
* the path within the tree of the commit * the path within the tree
* @throws FileNotFoundException * @throws FileNotFoundException
* the path does not exist in the commit's tree. * the path does not exist in the commit's tree.
* @throws IOException * @throws IOException
@ -111,16 +148,37 @@ public BlobBasedConfig(Config base, final Repository r,
* @throws ConfigInvalidException * @throws ConfigInvalidException
* the blob is not a valid configuration format. * the blob is not a valid configuration format.
*/ */
public BlobBasedConfig(Config base, final Commit commit, final String path) public BlobBasedConfig(Config base, Repository db, AnyObjectId treeish,
throws FileNotFoundException, IOException, ConfigInvalidException { String path) throws FileNotFoundException, IOException,
super(base); ConfigInvalidException {
final ObjectId treeId = commit.getTreeId(); this(base, read(db, treeish, path));
final Repository r = commit.getRepository(); }
final TreeWalk tree = TreeWalk.forPath(r, path, treeId);
if (tree == null) private static byte[] read(Repository db, AnyObjectId treeish, String path)
throw new FileNotFoundException(MessageFormat.format(JGitText.get().entryNotFoundByPath, path)); throws MissingObjectException, IncorrectObjectTypeException,
final ObjectId blobId = tree.getObjectId(0); IOException {
ObjectLoader loader = r.open(blobId,Constants.OBJ_BLOB); ObjectReader or = db.newObjectReader();
fromText(RawParseUtils.decode(loader.getCachedBytes())); try {
TreeWalk tree = TreeWalk.forPath(or, path, asTree(or, treeish));
if (tree == null)
throw new FileNotFoundException(MessageFormat.format(JGitText
.get().entryNotFoundByPath, path));
return read(or, tree.getObjectId(0));
} finally {
or.release();
}
}
private static AnyObjectId asTree(ObjectReader or, AnyObjectId treeish)
throws MissingObjectException, IncorrectObjectTypeException,
IOException {
if (treeish instanceof RevTree)
return treeish;
if (treeish instanceof RevCommit
&& ((RevCommit) treeish).getTree() != null)
return ((RevCommit) treeish).getTree();
return new RevWalk(or).parseTree(treeish).getId();
} }
} }

View File

@ -45,25 +45,19 @@
package org.eclipse.jgit.lib; package org.eclipse.jgit.lib;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.text.MessageFormat; import java.util.List;
import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.MissingObjectException;
/** /**
* Instances of this class represent a Commit object. It represents a snapshot * Mutable builder to construct a commit recording the state of a project.
* in a Git repository, who created it and when. *
* Applications should use this object when they need to manually construct a
* commit and want precise control over its fields. For a higher level interface
* see {@link org.eclipse.jgit.api.CommitCommand}.
*/ */
public class Commit implements Treeish { public class Commit {
private static final ObjectId[] EMPTY_OBJECTID_LIST = new ObjectId[0]; private static final ObjectId[] EMPTY_OBJECTID_LIST = new ObjectId[0];
private final Repository objdb;
private ObjectId commitId; private ObjectId commitId;
private ObjectId treeId; private ObjectId treeId;
@ -76,102 +70,21 @@ public class Commit implements Treeish {
private String message; private String message;
private Tree treeObj;
private byte[] raw;
private Charset encoding; private Charset encoding;
/** /** Initialize an empty commit. */
* Create an empty commit object. More information must be fed to this public Commit() {
* object to make it useful.
*
* @param db
* The repository with which to associate it.
*/
public Commit(final Repository db) {
objdb = db;
parentIds = EMPTY_OBJECTID_LIST; parentIds = EMPTY_OBJECTID_LIST;
encoding = Constants.CHARSET;
} }
/** /** @return this commit's object id. */
* Create a commit associated with these parents and associate it with a
* repository.
*
* @param db
* The repository to which this commit object belongs
* @param parentIds
* Id's of the parent(s)
*/
public Commit(final Repository db, final ObjectId[] parentIds) {
objdb = db;
this.parentIds = parentIds;
}
/**
* Create a commit object with the specified id and data from and existing
* commit object in a repository.
*
* @param db
* The repository to which this commit object belongs
* @param id
* Commit id
* @param raw
* Raw commit object data
*/
public Commit(final Repository db, final ObjectId id, final byte[] raw) {
objdb = db;
commitId = id;
treeId = ObjectId.fromString(raw, 5);
parentIds = new ObjectId[1];
int np=0;
int rawPtr = 46;
for (;;) {
if (raw[rawPtr] != 'p')
break;
if (np == 0) {
parentIds[np++] = ObjectId.fromString(raw, rawPtr + 7);
} else if (np == 1) {
parentIds = new ObjectId[] { parentIds[0], ObjectId.fromString(raw, rawPtr + 7) };
np++;
} else {
if (parentIds.length <= np) {
ObjectId[] old = parentIds;
parentIds = new ObjectId[parentIds.length+32];
for (int i=0; i<np; ++i)
parentIds[i] = old[i];
}
parentIds[np++] = ObjectId.fromString(raw, rawPtr + 7);
}
rawPtr += 48;
}
if (np != parentIds.length) {
ObjectId[] old = parentIds;
parentIds = new ObjectId[np];
for (int i=0; i<np; ++i)
parentIds[i] = old[i];
} else
if (np == 0)
parentIds = EMPTY_OBJECTID_LIST;
this.raw = raw;
}
/**
* @return get repository for the commit
*/
public Repository getRepository() {
return objdb;
}
/**
* @return The commit object id
*/
public ObjectId getCommitId() { public ObjectId getCommitId() {
return commitId; return commitId;
} }
/** /**
* Set the id of this object. * Set the id of this commit object.
* *
* @param id * @param id
* the id that we calculated for this object. * the id that we calculated for this object.
@ -180,6 +93,7 @@ public void setCommitId(final ObjectId id) {
commitId = id; commitId = id;
} }
/** @return id of the root tree listing this commit's snapshot. */
public ObjectId getTreeId() { public ObjectId getTreeId() {
return treeId; return treeId;
} }
@ -188,198 +102,197 @@ public ObjectId getTreeId() {
* Set the tree id for this commit object * Set the tree id for this commit object
* *
* @param id * @param id
* the tree identity.
*/ */
public void setTreeId(final ObjectId id) { public void setTreeId(AnyObjectId id) {
if (treeId==null || !treeId.equals(id)) { treeId = id.copy();
treeObj = null; commitId = null;
}
treeId = id;
} }
public Tree getTree() throws IOException { /** @return the author of this commit (who wrote it). */
if (treeObj == null) {
treeObj = objdb.mapTree(getTreeId());
if (treeObj == null) {
throw new MissingObjectException(getTreeId(),
Constants.TYPE_TREE);
}
}
return treeObj;
}
/**
* Set the tree object for this commit
* @see #setTreeId
* @param t the Tree object
*/
public void setTree(final Tree t) {
treeId = t.getTreeId();
treeObj = t;
}
/**
* @return the author and authoring time for this commit
*/
public PersonIdent getAuthor() { public PersonIdent getAuthor() {
decode();
return author; return author;
} }
/** /**
* Set the author and authoring time for this commit * Set the author (name, email address, and date) of who wrote the commit.
* @param a *
* @param newAuthor
* the new author. Should not be null.
*/ */
public void setAuthor(final PersonIdent a) { public void setAuthor(PersonIdent newAuthor) {
author = a; author = newAuthor;
commitId = null;
} }
/** /** @return the committer and commit time for this object. */
* @return the committer and commit time for this object
*/
public PersonIdent getCommitter() { public PersonIdent getCommitter() {
decode();
return committer; return committer;
} }
/** /**
* Set the committer and commit time for this object * Set the committer and commit time for this object
* @param c the committer information *
* @param newCommitter
* the committer information. Should not be null.
*/ */
public void setCommitter(final PersonIdent c) { public void setCommitter(PersonIdent newCommitter) {
committer = c; committer = newCommitter;
commitId = null;
} }
/** /** @return the ancestors of this commit. Never null. */
* @return the object ids of this commit
*/
public ObjectId[] getParentIds() { public ObjectId[] getParentIds() {
return parentIds; return parentIds;
} }
/** /**
* @return the commit message * Set the parent of this commit.
*
* @param newParent
* the single parent for the commit.
*/ */
public void setParentId(AnyObjectId newParent) {
parentIds = new ObjectId[] { newParent.copy() };
commitId = null;
}
/**
* Set the parents of this commit.
*
* @param parent1
* the first parent of this commit. Typically this is the current
* value of the {@code HEAD} reference and is thus the current
* branch's position in history.
* @param parent2
* the second parent of this merge commit. Usually this is the
* branch being merged into the current branch.
*/
public void setParentIds(AnyObjectId parent1, AnyObjectId parent2) {
parentIds = new ObjectId[] { parent1.copy(), parent2.copy() };
commitId = null;
}
/**
* Set the parents of this commit.
*
* @param newParents
* the entire list of parents for this commit.
*/
public void setParentIds(ObjectId... newParents) {
parentIds = new ObjectId[newParents.length];
for (int i = 0; i < newParents.length; i++)
parentIds[i] = newParents[i].copy();
commitId = null;
}
/**
* Set the parents of this commit.
*
* @param newParents
* the entire list of parents for this commit.
*/
public void setParentIds(List<? extends AnyObjectId> newParents) {
parentIds = new ObjectId[newParents.size()];
for (int i = 0; i < newParents.size(); i++)
parentIds[i] = newParents.get(i).copy();
commitId = null;
}
/**
* Add a parent onto the end of the parent list.
*
* @param additionalParent
* new parent to add onto the end of the current parent list.
*/
public void addParentId(AnyObjectId additionalParent) {
if (parentIds.length == 0) {
setParentId(additionalParent);
} else {
ObjectId[] newParents = new ObjectId[parentIds.length + 1];
for (int i = 0; i < parentIds.length; i++)
newParents[i] = parentIds[i];
newParents[parentIds.length] = additionalParent.copy();
parentIds = newParents;
commitId = null;
}
}
/** @return the complete commit message. */
public String getMessage() { public String getMessage() {
decode();
return message; return message;
} }
/** /**
* Set the parents of this commit * Set the commit message.
* @param parentIds *
* @param newMessage
* the commit message. Should not be null.
*/ */
public void setParentIds(ObjectId[] parentIds) { public void setMessage(final String newMessage) {
this.parentIds = new ObjectId[parentIds.length]; message = newMessage;
for (int i=0; i<parentIds.length; ++i)
this.parentIds[i] = parentIds[i];
}
private void decode() {
// FIXME: handle I/O errors
if (raw != null) {
try {
DataInputStream br = new DataInputStream(new ByteArrayInputStream(raw));
String n = br.readLine();
if (n == null || !n.startsWith("tree ")) {
throw new CorruptObjectException(commitId, JGitText.get().corruptObjectNotree);
}
while ((n = br.readLine()) != null && n.startsWith("parent ")) {
// empty body
}
if (n == null || !n.startsWith("author ")) {
throw new CorruptObjectException(commitId, JGitText.get().corruptObjectNoAuthor);
}
String rawAuthor = n.substring("author ".length());
n = br.readLine();
if (n == null || !n.startsWith("committer ")) {
throw new CorruptObjectException(commitId, JGitText.get().corruptObjectNoCommitter);
}
String rawCommitter = n.substring("committer ".length());
n = br.readLine();
if (n != null && n.startsWith( "encoding"))
encoding = Charset.forName(n.substring("encoding ".length()));
else
if (n == null || !n.equals("")) {
throw new CorruptObjectException(commitId, MessageFormat.format(
JGitText.get().corruptObjectMalformedHeader, n));
}
byte[] readBuf = new byte[br.available()]; // in-memory stream so this is all bytes left
br.read(readBuf);
int msgstart = readBuf.length != 0 ? ( readBuf[0] == '\n' ? 1 : 0 ) : 0;
// If encoding is not specified, the default for commit is UTF-8
if (encoding == null) encoding = Constants.CHARSET;
// TODO: this isn't reliable so we need to guess the encoding from the actual content
author = new PersonIdent(new String(rawAuthor.getBytes(),encoding.name()));
committer = new PersonIdent(new String(rawCommitter.getBytes(),encoding.name()));
message = new String(readBuf,msgstart, readBuf.length-msgstart, encoding.name());
} catch (IOException e) {
e.printStackTrace();
} finally {
raw = null;
}
}
} }
/** /**
* Set the commit message * Set the encoding for the commit information
* *
* @param m the commit message * @param encodingName
* the encoding name. See {@link Charset#forName(String)}.
*/ */
public void setMessage(final String m) { public void setEncoding(String encodingName) {
message = m; encoding = Charset.forName(encodingName);
} }
/** /**
* Persist this commit object * Set the encoding for the commit information
* *
* @throws IOException * @param enc
* the encoding to use.
*/ */
public void commit() throws IOException { public void setEncoding(Charset enc) {
if (getCommitId() != null) encoding = enc;
throw new IllegalStateException(MessageFormat.format(JGitText.get().commitAlreadyExists, getCommitId()));
ObjectInserter odi = objdb.newObjectInserter();
try {
ObjectId id = odi.insert(Constants.OBJ_COMMIT, odi.format(this));
odi.flush();
setCommitId(id);
} finally {
odi.release();
}
} }
/** @return the encoding that should be used for the commit message text. */
public Charset getEncoding() {
return encoding;
}
@Override
public String toString() { public String toString() {
return "Commit[" + ObjectId.toString(getCommitId()) + " " + getAuthor() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ StringBuilder r = new StringBuilder();
} r.append("Commit");
if (commitId != null)
r.append("[" + commitId.name() + "]");
r.append("={\n");
/** r.append("tree ");
* State the encoding for the commit information r.append(treeId != null ? treeId.name() : "NOT_SET");
* r.append("\n");
* @param e
* the encoding. See {@link Charset}
*/
public void setEncoding(String e) {
encoding = Charset.forName(e);
}
/** for (ObjectId p : parentIds) {
* State the encoding for the commit information r.append("parent ");
* r.append(p.name());
* @param e r.append("\n");
* the encoding. See {@link Charset} }
*/
public void setEncoding(Charset e) {
encoding = e;
}
/** r.append("author ");
* @return the encoding used. See {@link Charset} r.append(author != null ? author.toString() : "NOT_SET");
*/ r.append("\n");
public String getEncoding() {
if (encoding != null) r.append("committer ");
return encoding.name(); r.append(committer != null ? committer.toString() : "NOT_SET");
else r.append("\n");
return null;
if (encoding != null && encoding != Constants.CHARSET) {
r.append("encoding ");
r.append(encoding.name());
r.append("\n");
}
r.append("\n");
r.append(message != null ? message : "");
r.append("}");
return r.toString();
} }
} }

View File

@ -53,6 +53,7 @@
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.text.MessageFormat; import java.text.MessageFormat;
@ -304,10 +305,7 @@ public final byte[] format(Tree tree) throws IOException {
*/ */
public final byte[] format(Commit commit) public final byte[] format(Commit commit)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
String encoding = commit.getEncoding(); Charset encoding = commit.getEncoding();
if (encoding == null)
encoding = Constants.CHARACTER_ENCODING;
ByteArrayOutputStream os = new ByteArrayOutputStream(); ByteArrayOutputStream os = new ByteArrayOutputStream();
OutputStreamWriter w = new OutputStreamWriter(os, encoding); OutputStreamWriter w = new OutputStreamWriter(os, encoding);
try { try {
@ -316,11 +314,10 @@ public final byte[] format(Commit commit)
commit.getTreeId().copyTo(os); commit.getTreeId().copyTo(os);
os.write('\n'); os.write('\n');
ObjectId[] ps = commit.getParentIds(); for (ObjectId p : commit.getParentIds()) {
for (int i = 0; i < ps.length; ++i) {
os.write(hparent); os.write(hparent);
os.write(' '); os.write(' ');
ps[i].copyTo(os); p.copyTo(os);
os.write('\n'); os.write('\n');
} }
@ -336,16 +333,19 @@ public final byte[] format(Commit commit)
w.flush(); w.flush();
os.write('\n'); os.write('\n');
if (!encoding.equals(Constants.CHARACTER_ENCODING)) { if (encoding != Constants.CHARSET) {
os.write(hencoding); os.write(hencoding);
os.write(' '); os.write(' ');
os.write(Constants.encodeASCII(encoding)); os.write(Constants.encodeASCII(encoding.name()));
os.write('\n'); os.write('\n');
} }
os.write('\n'); os.write('\n');
w.write(commit.getMessage());
w.flush(); if (commit.getMessage() != null) {
w.write(commit.getMessage());
w.flush();
}
} catch (IOException err) { } catch (IOException err) {
// This should never occur, the only way to get it above is // This should never occur, the only way to get it above is
// for the ByteArrayOutputStream to throw, but it doesn't. // for the ByteArrayOutputStream to throw, but it doesn't.

View File

@ -270,84 +270,6 @@ public ObjectLoader open(AnyObjectId objectId, int typeHint)
return getObjectDatabase().open(objectId, typeHint); return getObjectDatabase().open(objectId, typeHint);
} }
/**
* Access a Commit object using a symbolic reference. This reference may
* be a SHA-1 or ref in combination with a number of symbols translating
* from one ref or SHA1-1 to another, such as HEAD^ etc.
*
* @param revstr a reference to a git commit object
* @return a Commit named by the specified string
* @throws IOException for I/O error or unexpected object type.
*
* @see #resolve(String)
* @deprecated Use {@link #resolve(String)} and pass its return value to
* {@link org.eclipse.jgit.revwalk.RevWalk#parseCommit(AnyObjectId)}.
*/
@Deprecated
public Commit mapCommit(final String revstr) throws IOException {
final ObjectId id = resolve(revstr);
return id != null ? mapCommit(id) : null;
}
/**
* Access any type of Git object by id and
*
* @param id
* SHA-1 of object to read
* @param refName optional, only relevant for simple tags
* @return The Git object if found or null
* @throws IOException
* @deprecated Use {@link org.eclipse.jgit.revwalk.RevWalk#parseCommit(AnyObjectId)},
* or {@link org.eclipse.jgit.revwalk.RevWalk#parseTag(AnyObjectId)}.
* To read a tree, use {@link org.eclipse.jgit.treewalk.TreeWalk#addTree(AnyObjectId)}.
* To read a blob, open it with {@link #open(AnyObjectId)}.
*/
@Deprecated
public Object mapObject(final ObjectId id, final String refName) throws IOException {
final ObjectLoader or;
try {
or = open(id);
} catch (MissingObjectException notFound) {
return null;
}
final byte[] raw = or.getCachedBytes();
switch (or.getType()) {
case Constants.OBJ_TREE:
return new Tree(this, id, raw);
case Constants.OBJ_COMMIT:
return new Commit(this, id, raw);
case Constants.OBJ_TAG:
return new Tag(this, id, refName, raw);
case Constants.OBJ_BLOB:
return raw;
default:
throw new IncorrectObjectTypeException(id,
JGitText.get().incorrectObjectType_COMMITnorTREEnorBLOBnorTAG);
}
}
/**
* Access a Commit by SHA'1 id.
* @param id
* @return Commit or null
* @throws IOException for I/O error or unexpected object type.
* @deprecated Use {@link org.eclipse.jgit.revwalk.RevWalk#parseCommit(AnyObjectId)}.
*/
@Deprecated
public Commit mapCommit(final ObjectId id) throws IOException {
final ObjectLoader or;
try {
or = open(id, Constants.OBJ_COMMIT);
} catch (MissingObjectException notFound) {
return null;
}
return new Commit(this, id, or.getCachedBytes());
}
/** /**
* Access a Tree object using a symbolic reference. This reference may * Access a Tree object using a symbolic reference. This reference may
* be a SHA-1 or ref in combination with a number of symbols translating * be a SHA-1 or ref in combination with a number of symbols translating

View File

@ -53,7 +53,6 @@
import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Commit;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.MutableObjectId; import org.eclipse.jgit.lib.MutableObjectId;
import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.PersonIdent;
@ -206,18 +205,6 @@ public final int getCommitTime() {
return commitTime; return commitTime;
} }
/**
* Parse this commit buffer for display.
*
* @param walk
* revision walker owning this reference.
* @return parsed commit.
*/
public final Commit asCommit(final RevWalk walk) {
// TODO(spearce) Remove repository when this method dies.
return new Commit(walk.repository, this, buffer);
}
/** /**
* Get a reference to this commit's tree. * Get a reference to this commit's tree.
* *