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

Tracking a merge bug

From
Ephrim Khong <dr.khong@gmail.com>
Date
Oct 26, 2020, 15:08 UTC
Message-ID
<120922f1-67a9-9ae2-2e9c-56e20935e0f9@gmail.com>
Dear All,

I am trying to find the root cause for what I believe might be a strange bug in git merge. I have a feature branch A which branched off master not too long ago, and want to bring it up to date with master:

    git checkout A
    git merge master
which yields
    Removing somefile
    Removing anotherfile
    error: add_cacheinfo failed to refresh for path 'c/d/e.sh'; merge
aborting.

the offending file, c/d/e.sh, does not exist in my feature branch but was added to master since branching off. After aborting, the working directory is in an inconsistent state and c/d/e.sh exists with the correct content.

Below is a stacktrace - the merger handles the file as a rename (apparently there is a similar / identical file 'c/f/g.sh' that is renamed to 'c/d/e.sh'), but that fails because the file has MODE_CHANGED set. (Which appears strange - at the time where the merge is aborting, the file apparently was already written to the working directory. Is it renaming two different files to the same target file?).

Any hint is appreciated, especially where to look: Is the root cause more likely to be at the filesystem level (the stat returns something off), or in the merge logic? What else could be wrong here?

The stacktrace looks roughly as follows:
-> read-cache.c, ie_modified(): ie_match_stat returned 63, which is
		MTIME_CHANGED	| CTIME_CHANGED | OWNER_CHANGED |
		MODE_CHANGED | INODE_CHANGED | DATA_CHANGED
	and is_modified() returns 63 because MODE_CHANGED is set.
-> read-cache.c, refresh_cache_ent(): at the call to ie_modified
-> read-cache.c, refresh_cache_entry()

-> merge-recursive.c, add_cacheinfo(), is in the refresh-path (i.e. make_cache_entry() worked, but refresh_cache_entry() will fail)

-> merge-recursive.c, update_file_flags(), after the update_index: label
-> merge-recursive.c, update_file()

-> merge-recursive.c, handle_content_merge() is in the very last update_file() call, close to the end of the function

-> merge-recursive.c, handle_rename_normal()
-> merge-recursive.c, process_entry()
	is in the RENAME_NORMAL / RENAME_ONE_FILE_TO_ONE block
-> [...]
Thanks
- Eph
Next: Elijah Newren
Message 1 of 3 in “Tracking a merge bug”
  1. Ephrim KhongOct 26, 2020
  2. Elijah NewrenOct 26, 2020
  3. Ephrim KhongMar 5, 2021

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.