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

Re: SEGV in git-merge recursive:

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Mar 30, 2007, 21:00 UTC
Message-ID
<Pine.LNX.4.63.0703302239050.4045@wbgn013.biozentrum.uni-wuerzburg.de>
In-Reply-To
<Pine.LNX.4.64.0703291237240.6730@woody.linux-foundation.org>
Hi,
On Thu, 29 Mar 2007, Linus Torvalds wrote:
Show 17 quoted lines
> On Thu, 29 Mar 2007, Linus Torvalds wrote:
> 
> > It's not the initial commit. It's a criss-cross merge, and it's a 
> > virtual commit created by a previous level of merging.
> > 
> > Apply this patch to see it blow up much earlier, when that bogus 
> > commit with a NULL tree is created.
> > 
> > (I didn't debug *why* that happens, but maybe this gets somebody 
> > further)
> 
> Well, it happens because "git_write_tree()" returns NULL. Which in turn 
> is because "unmerged_index()" returns true.
> 
> merge_trees() tries to clean up the unmerged index, but apparently 
> doesn't do good enough of a job, so git_write_tree() is called with 
> entries still unmerged..
Actually, this is not the complete truth.

This particular case has a conflicting rename/rename in an _intermediate_ commit. This _cannot_ be resolved automatically, not even by putting conflict markers into the appropriate files (*1*).

IMHO, there is actually no way merge_trees() can fix the conflicts enough to write a tree.

So, the only way I see to avoid that SEGV is to something like this:
diff --git a/merge-recursive.c b/merge-recursive.c
index ece2238..cbc39e9 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -1135,8 +1135,13 @@ static int merge_trees(struct tree *head,
 	else
 		clean = 1;
 
-	if (index_only)
+	if (index_only) {
 		*result = git_write_tree();
+		if (!*result) {
+			flush_output();
+			die ("cannot continue merging.");
+		}
+	}
 
 	return clean;
 }

NOTE: I will not make the error again _not_ to point out that this is 
_just_ a hint at what a proper patch would look like.

For example, a proper patch would include a test case, _and_ would print a 
proper hint about GIT_MERGE_VERBOSITY (otherwise, you will only get a 
fatal error "cannot continue merging", without any hint about what went 
wrong).

Ciao,
Dscho

*1* I played with the idea to do a threeway merge of the conflicting files 
(src->dst1,dst2, using src as common version), but I am not quite sure if 
it is worth the confusion it seeds.

Besides, there is another type of rename/rename conflict, which _cannot_ 
be solved in that manner: (src1,src2->dst). And for this case, we have to 
have a sane way out anyway.
Previous: Alex RiesenNext: Linus Torvalds
Message 19 of 31 in “SEGV in git-merge recursive:”
  1. Tom PrinceMar 29, 2007
  2. Alex RiesenMar 29, 2007
  3. Tom PrinceMar 29, 2007
  4. Alex RiesenMar 29, 2007
  5. Tom PrinceMar 29, 2007
  6. Alex RiesenMar 29, 2007
  7. Tom PrinceMar 29, 2007
  8. Alex RiesenMar 29, 2007
  9. Alex RiesenMar 29, 2007
  10. Tom PrinceMar 29, 2007
  11. Alex RiesenMar 29, 2007
  12. Alex RiesenMar 29, 2007
  13. Alex RiesenMar 29, 2007
  14. An attempt to resolve a rename/rename conflict in recursive mergeAlex Riesen, Mar 29, 2007
  15. Alex RiesenMar 29, 2007
  16. Linus TorvaldsMar 29, 2007
  17. Linus TorvaldsMar 29, 2007
  18. Alex RiesenMar 29, 2007
  19. Johannes SchindelinMar 30, 2007
  20. Linus TorvaldsMar 31, 2007
  21. Linus TorvaldsMar 31, 2007
  22. Alex RiesenMar 31, 2007
  23. Keep rename/rename conflicts of intermediate merges while doing recursive mergeAlex Riesen, Mar 31, 2007
  24. Jakub NarebskiMar 31, 2007
  25. Johannes SchindelinMar 31, 2007
  26. Johannes SchindelinMar 31, 2007
  27. Linus TorvaldsMar 31, 2007
  28. Alex RiesenMar 31, 2007
  29. Junio C HamanoMar 31, 2007
  30. Johannes SchindelinMar 31, 2007
  31. Tom PrinceMar 29, 2007

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.