From: Philippe Blain Date: Wed, 30 Sep 2026 18:31:44 GMT Subject: Re: [BUG] submodule merge tries to read B's commit from A Message-ID: <764b8c2e-cf09-4531-94f2-268f97a889d7@gmail.com> In-Reply-To: Hi Guillaume, Le 2026-09-23 à 16 h 20, Guillaume CHAUVEL a écrit : > I ran into two problems while merging a superproject with submodules. > > One problem, involving the repository used for commit-graph lookups, was > reported in this thread: > https://lore.kernel.org/git/d3241733-d015-4646-88e0-06e56a04e77b@nutanix.com/T/#m174067937aaf76e9fa844386961b3e9e66c1e4d9 FYI, the above bug was fixed in 700f7b74de (commit-reach: parse commits in the given repository, 2026-09-16), which is currently in 'next' but not yet in master. > The other problem is that during a merge, Git sometimes tries to read > from submodule A a commit that exists only in submodule B. I reproduced > this with Git v2.56.0-rc2, built from source in an Ubuntu 26.04 > container and an Alpine container. The reproducer below triggered the > issue in all 50 Ubuntu runs and in 43 out of 50 Alpine runs. > > The merge should report a submodule conflict, not look for B's commit > in A or report A as corrupt. The script checks the OID's presence in > both submodules and prints the "BUG" line when it finds this case. Thanks for the reproducer, I confirm I see the same behaviour with v2.56.0-rc2, on RHEL 9. With v2.48.1, the merge results in a conflict, instead of aborting, although I get a spurious "hash mismatch" message, and the reason for the conflict ("commits not present") is wrong: git version 2.48.1 git merge exit status: 1 error: hash mismatch 2ca9f0f330e976b992fc18633d1d267b8aad596e Failed to merge submodule A (commits not present) CONFLICT (submodule): Merge conflict in A Failed to merge submodule B CONFLICT (submodule): Merge conflict in B Automatic merge failed; fix conflicts and then commit the result. With 2.33.0, which I chose randomly, we get the correct behaviour: git version 2.33.0 git merge exit status: 1 Failed to merge submodule A CONFLICT (submodule): Merge conflict in A Failed to merge submodule B CONFLICT (submodule): Merge conflict in B Automatic merge failed; fix conflicts and then commit the result. I turned your reproducer into a bisection script (~/bisect-merge.sh) by tweaking the final 'if': ``` if [[ $merge_output =~ Could\ not\ read\ ([0-9a-f]{40}|[0-9a-f]{64}) ]]; then foreign_oid=${BASH_REMATCH[1]} if ! (cd A && git cat-file -e "$foreign_oid" 2>/dev/null) && (cd B && git cat-file -e "$foreign_oid" 2>/dev/null); then printf 'BUG: OID %s belongs to B instead of A\n' "$foreign_oid" exit 1 fi elif [[ $merge_output =~ hash\ mismatch ]];then [ ${1:-""} = MISMATCH ] && exit 1 || exit 0 else exit 0 fi ``` and invoking it in my ~/bisect-git.sh script: ``` #!/bin/bash make clean > /dev/null # build but keep the output on one line if make -j |& { while read line; do printf "\033[K%s\r" "${line}" ; done; printf "\033[KFinished building $(cat GIT-VERSION-FILE)\n" ; } then # run project specific test and report its status export PATH="$PWD/bin-wrappers/:$PATH" ~/bisect-merge.sh "$@" status=$? else # tell the caller this is untestable status=125 fi # return control echo exit $status ``` Bisecting the merge failure with: git bisect start v2.56.0-rc2 v2.48.1 && git bisect run ~/bisect-git.sh finds bb5da75d61 (commit: use commit graph in lookup_commit_reference_gently(), 2026-02-16), i.e. v2.54.0-rc0~136^2, which is the same commit from which the commit-graph bug mentioned above originates. I CC'ed Patrick, its author. Bisecting the "hash mismatch" behaviour with: git bisect start v2.48.1 v2.33.0 && git bisect run ~/bisect-git.sh MISMATCH finds 6f1e9394e2 (object: fix leaking packfiles when closing object store, 2024-08-08), i.e. v2.47.0-rc0~123^2, which is also authored by Patrick. I did not yet dig further, but I have a few additional observations: - in contrast to the commit-graph bug, disabling the use of commit-graphs via 'git config --global core.commitGraph false' early in the script, by moving the 'tmpdir' definition to the top and setting GIT_CONFIG_GLOBAL=$tmpdir/.gitconfig, does not change the behaviour, neither in the "repository corrupt" case, nor in the "hash mismatch" case. - On Ubuntu 22.02 under WSL, the reproducer does not trigger the bug on v2.56.0-rc2 (on a dozen runs), but it does trigger it on v2.55.0. Funnily on that system with v2.56.0-rc2 I get the correct behaviour ! (no "hash mismatch" either). - On a Ubuntu 22.04 Docker container, I get the same behaviour as on RHEL 9. > An AI analysis identified a likely cause: a delta-base cache entry may > remain after its pack is closed. If a pack from another submodule reuses > the same packed_git address and base offset, Git may return stale cached > data. >