git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [JGIT] help needed to create a siimple commit

From
Shawn O. Pearce <spearce@spearce.org>
Date
Feb 4, 2009, 17:07 UTC
Message-ID
<20090204170729.GB26880@spearce.org>
In-Reply-To
<551f769b0902040810o6b45008fgcc1ef70108b3d90@mail.gmail.com>
Yann Simon <yann.simon.fr@gmail.com> wrote:
Show 5 quoted lines
> 		final Commit commit = new Commit(db);
> 		commit.setAuthor(new PersonIdent(jauthor, 1154236443000L, -4 * 60));
> 		commit.setCommitter(new PersonIdent(jcommitter, 1154236443000L, -4 * 60));
> 		commit.setMessage(commitMessage);
> 		commit.setTree(tree);

FWIW, its faster to use setTreeId(). Then you don't need to use mapTree to read the tree object into memory. This is an older area of the Commit class API, before we understood how important it was to avoid processing unnecessary data. :-)

Show 5 quoted lines
> 		assertEquals(tree.getTreeId(), commit.getTreeId());
> 		commit.commit();
> 		
> 		ObjectWriter writer = new ObjectWriter(db);
> 		commit.setCommitId(writer.writeCommit(commit));
Uh, commit.commit() is doing the same work as the above two lines,
so these above two lines are a no-op as the object already exists
in the object database.
 
Show 9 quoted lines
> 		Ref oldHEAD = db.getAllRefs().get(Constants.HEAD);
> 		final RefUpdate ru = db.updateRef(Constants.HEAD);
> 		ru.setNewObjectId(commit.getCommitId());
> 		ru.setRefLogMessage(commitMessage, false);
> 
> 		if (oldHEAD != null) {
> 			// commit has parents
> 			ru.setExpectedOldObjectId(oldHEAD.getObjectId());
> 			assertSame(RefUpdate.Result.FAST_FORWARD, ru.update());

This fails because the commit has no parents, but you asked for a fast-forward update. Since HEAD already has a commit, and the new commit isn't a super-set of the existing HEAD, and RefUpdate.isForceUpdate() is false, the update is being rejected.

If you really mean to replace the commit, e.g. commit --amend, you need to ru.setForceUpdate(true).

If you really mean to fast-forward the commit, e.g. just make a new commit on top of the existing commits, you need to do the read to get oldHEAD *before* you call commit.commit() above, and use:

  commit.setParents(new Object[]{ oldHEAD.getObjectId() })

to set the current commit as the first parent of the new commit, so the new commit is really a superset of the old one.

Again, back to the basic DAG in Git... JGit is just a library with the building blocks necessary to manipulate the DAG. Its up to the appliction to create the new nodes correctly for its needs, and to make the right requests to RefUpdate. The RefUpdate API is designed to help the application enforce CAS semantics, to avoid race conditions and other ugly surprises.

-- 
Shawn.
Previous: Yann Simon
Message 4 of 4 in “[JGIT] help needed to create a siimple commit”
  1. Yann SimonFeb 3, 2009
  2. Shawn O. PearceFeb 3, 2009
  3. Yann SimonFeb 4, 2009
  4. Shawn O. PearceFeb 4, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.