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

Bug in merge-recursive in virtual commit corner case

From
Shawn Pearce <spearce@spearce.org>
Date
Dec 7, 2006, 08:35 UTC
Message-ID
<20061207083531.GA22701@spearce.org>

So I managed to create a fairly complex set of branches which are all merged back against each other at various points in time. Two of them have 3 merge bases according to git-merge-base. Tonight I tried to merge them together, but received the following wonderful error from git-merge-recursive:

  fatal: unable to read source tree (4b825dc642cb6eb9a060e54bf8d69288fbee4904)

For those in the know, that's the empty tree. This particular repository does not have the empty tree anywhere in it, which is why we can't read the object: it doesn't exist, and shouldn't exist.

Running `git-mktree </dev/null` to create the empty tree worked; git-merge-recursive ran through and cleanly merged the two branches. But the empty tree still shouldn't be in my repository, so a future git-prune is just going to whack it again. Yes, I know, I could anchor it with a ref (.git/refs/empty-tree) but I shouldn't need to use git-mktree and git-update-ref just to use git-merge-recursive.

I found the above error message in tree-diff.c's diff_tree_sha1 function. I threw in debugging and found that the new tree was the root tree of one branch and the base was the root tree of some other revision.

Apparently the empty tree is being created in merge-recursive.c:
   1219     if (merged_common_ancestors == NULL) {
   1220         /* if there is no common ancestor, make an empty tree */
   1221         struct tree *tree = xcalloc(1, sizeof(struct tree));
   1222
   1223         tree->object.parsed = 1;
   1224         tree->object.type = OBJ_TREE;
   1225         hash_sha1_file(NULL, 0, tree_type, tree->object.sha1);
   1226         merged_common_ancestors = make_virtual_commit(tree, "ancestor");
   1227     }

So basically this code crashes if its ever used in a repository that hasn't had a need for the empty tree before. :-(

I've been unable to create an isolated test case. I can't publish the repository that I caused the case in either.

I'm not quite sure what the fix should be here: patch diff_tree_sha1 to know when it gets the empty tree, or create the object in merge-recursive.c?

Next: Junio C Hamano
Message 1 of 6 in “Bug in merge-recursive in virtual commit corner case”
  1. Shawn PearceDec 7, 2006
  2. Junio C HamanoDec 7, 2006
  3. Johannes SchindelinDec 7, 2006
  4. Shawn PearceDec 7, 2006
  5. Johannes SchindelinDec 8, 2006
  6. Junio C HamanoDec 8, 2006

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.