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

BUG() during criss-cross merge with directory rename and deleted file

From
Emily Shaffer <emilyshaffer@google.com>
Date
Jul 26, 2019, 22:09 UTC
Message-ID
<20190726220928.GG113966@google.com>
Hi all,

As mentioned during the standup in #git-devel today, we encountered a BUG() during certain circumstances of a criss-cross merge. Timing has prevented me from getting the repro case together to send just yet, but it appears that the issue is as follows:

 - During a merge in a repo with fairly complicated, merge-y history,
   the following BUG() is seen:
   "BUG: There are unmerged index entries:
    BUG: 2 baz/bar.txt
    BUG: merge-recursive.c:429: unmerged index entries in
    merge-recursive.c
    Aborted"
 - But when the user then runs `git status` (after clearing
   .git/index.lock) the directory is clean.
 - The repo does not contain a 'baz/bar.txt' (although 'baz/' exists).
 - In the repo's history a 'foo/bar.txt' can be found (that is the only
   'bar.txt' to ever exist in the project).
Digging further shows:
 - The merge had  multiple closest shared ancestors (criss-cross
   merge)
 - Directory 'foo/' was renamed on one side to 'baz/'...
 - ...and 'foo/bar.txt' was deleted on the other side.
 - When the virtual ancestor is generated, the directory rename can't be
   resolved and leaves a conflict.
 - The virtual ancestor being written to disk is in a conflicted state.
 - This causes the top-level merge to fail, printing the BUG() above
   which references a 'baz/bar.txt' that never really lived there.
Furthermore...
 - If merge.directoryrenames is set to any value besides "conflict", the
   merge succeeds (no BUG() generated).

This seems to have been introduced in 8c8e5bd6eb331d055aa7fa6345f6dcdadd658979 although I haven't bisected it yet.

It seems like the solution is to watch for whether we're making a virtual ancestor during a recursive merge, and if so, to treat merge.directoryrenames = "conflict" as "true" or "false" instead.

I plan to modify the tests added in 8c8e5bd6 to highlight this issue (just haven't had time, and probably won't til next week), and send a patch doing the special treatment on merge.directoryrenames.

Happy to hear other ideas folks have.
 - Emily
Next: Elijah Newren
Message 1 of 11 in “BUG() during criss-cross merge with directory rename and deleted file”
  1. Emily ShafferJul 26, 2019
  2. 1/1 merge-recursive: avoid directory rename detection in recursive caseElijah Newren, Aug 5, 2019
  3. Junio C HamanoAug 6, 2019
  4. Elijah NewrenAug 6, 2019
  5. Junio C HamanoAug 6, 2019
  6. Junio C HamanoAug 6, 2019
  7. Elijah NewrenAug 6, 2019
  8. Emily ShafferAug 6, 2019
  9. Elijah NewrenAug 6, 2019
  10. Emily ShafferAug 6, 2019
  11. Jeff KingAug 8, 2019

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.