From: Philippe Blain <levraiphilippeblain@gmail.com>
To: Guillaume CHAUVEL <guillaume.chauvel@gmail.com>, git@vger.kernel.org
Cc: ps@pks.im
Subject: Re: [BUG] submodule merge tries to read B's commit from A
Date: Wed, 30 Sep 2026 14:31:44 -0400 [thread overview]
Message-ID: <764b8c2e-cf09-4531-94f2-268f97a889d7@gmail.com> (raw)
In-Reply-To: <CAP4DsUexEmm1qo6jH+Qzy+n3dQs_OCJ8yg=ReF+aVrcTrC7NeQ@mail.gmail.com>
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.
>
next prev parent reply other threads:[~2026-09-30 18:31 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-23 20:20 [BUG] submodule merge tries to read B's commit from A Guillaume CHAUVEL
2026-09-30 18:31 ` Philippe Blain [this message]
2026-10-01 14:09 ` Patrick Steinhardt
2026-10-02 8:10 ` Patrick Steinhardt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=764b8c2e-cf09-4531-94f2-268f97a889d7@gmail.com \
--to=levraiphilippeblain@gmail.com \
--cc=git@vger.kernel.org \
--cc=guillaume.chauvel@gmail.com \
--cc=ps@pks.im \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox