Bug in merge-recursive in virtual commit corner case

Previous thread: [PATCH] Add config example with respect to branch by Aneesh Kumar K.V on Thursday, December 7, 2006 - 2:36 am. (2 messages)

Next thread: [PATCH 1/2] Allow users to require source branch on git-checkout -b. by Shawn O. Pearce on Thursday, December 7, 2006 - 6:01 am. (12 messages)
To: <git@...>
Date: Thursday, December 7, 2006 - 4:35 am

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 h...

To: Shawn Pearce <spearce@...>
Cc: <git@...>
Date: Thursday, December 7, 2006 - 11:38 am

Hi,

I think there is something else wrong. If you have three merge bases, I do
not see how you could get into that particular code path.

Any possibility for me to have a private look at your repo?

Ciao,
Dscho

-

To: Johannes Schindelin <Johannes.Schindelin@...>
Cc: <git@...>
Date: Thursday, December 7, 2006 - 3:24 pm

Arrgh. I can redo the merge and try to debug it myself; maybe I
can at least get enough details about what's going on to create a

No, unfortunately for me (I wish I could let you debug this!).
Far too many legal issues are involved. There is possible jail
time on my part for sharing any of the files in there... ;-)

Although Junio mentioned he recently saw something like this in
git.git when he merged in your xdl_merge() code. I wonder if its
the same issue.

--
Shawn.
-

To: Shawn Pearce <spearce@...>
Cc: Johannes Schindelin <Johannes.Schindelin@...>, <git@...>
Date: Friday, December 8, 2006 - 2:01 am

No, that is not related at all. My initial attempt (which is
not in any commit that survives til today) used hash_sha1_file()
on the result from xdl_merge() where I should have used
write_sha1_file(), and I saw the same "oh, the required object
is not there" errors from everywhere.

-

To: Shawn Pearce <spearce@...>
Cc: <git@...>
Date: Thursday, December 7, 2006 - 11:03 pm

Hi,

can you send me at least the output of

$ git-rev-list --parents branch1 branch2

preferrably packed? There is nothing you can do legally wrong, since you
are not sending any data, only metadata.

Ciao,
Dscho

-

To: Shawn Pearce <spearce@...>
Cc: <git@...>
Date: Thursday, December 7, 2006 - 5:13 am

I hit the same issue when I integrated Johannes's in-core merge;
I originally used hash_sha1_file() but that results in objects
that are supposed to be in the virtual parent unreadable when
merging the real children. The key is to use write_sha1_file()
to actually create the needed objects, and trust later prune to
remove them.

Replace it with write_sha1_file() and you should be fine, I
think.

-

Previous thread: [PATCH] Add config example with respect to branch by Aneesh Kumar K.V on Thursday, December 7, 2006 - 2:36 am. (2 messages)

Next thread: [PATCH 1/2] Allow users to require source branch on git-checkout -b. by Shawn O. Pearce on Thursday, December 7, 2006 - 6:01 am. (12 messages)