From: Martin Veilleux Date: Wed, 08 May 2024 23:45:03 GMT Subject: [BUG] fetch error when arbitrary branch changes a submodule url Message-ID: <8c53a956-13e9-4c7e-9359-2c86c9dd9908@gameloft.com> issue: fetch will give a fatal error once when a new arbitrary branch on the remote contains a submodule url change with updated sha This was an issue I originally opened on git-for-windows a while back. (https://github.com/git-for-windows/git/issues/3404) But it's actually reproducible on Linux Seems to be a regression since I could not repro on version 1.9 Issue still present on version 2.45.0.31.gd4cc1ec35f Local repro steps (complete test script attached) - create repo A with a commit on master - create repo B with a commit on master - create repo X and add a submodule S1 pointing to A, commit to master. - clone repo X with submodules to repo Z - in repo X, create branch X1 from master. Change submodule S1 url to repo B and commit on X1. - in repo Z, fetch and notice the fatal error "upload-pack: not our ref SHA" From there, you can then quickly repro the error like so: - in repo Z , delete branch origin/X1 and then fetch again. Current workaround is to set submodule.recurse to false -- Martin #!/bin/bash die() { echo "FATAL program error" exit 1 } gitTry() { echo "git $*" git $* } gitNoFail() { echo "git $*" git $* || die } createRepo() { local name=$1 [[ -n "$name" ]] || die mkdir $name || die pushd $name >/dev/null pwd gitNoFail init echo line1>readme.txt gitNoFail add readme.txt gitNoFail commit -m first popd >/dev/null echo "created git repo '$name'" } printHeader() { echo "==============================================================" if [[ -n "$1" ]]; then echo "$1" echo "==============================================================" fi } setupEnv() { if [[ -n "$GIT_PATH" ]]; then [[ -e "$GIT_PATH/git" ]] || die echo "user provided custom git in ${GIT_PATH}" export PATH="${GIT_PATH}:${PATH}" gitNoFail --version fi } main() { setupEnv local root=$(pwd) rm -rf child{1,2} user1 server1 local gitArgs="-c protocol.file.allow=always" #create submodule repos printHeader "create submodule repo 1" createRepo child1 printHeader "create submodule repo 2" createRepo child2 #workaround for identical initial SHA (is this a bug?) pushd child2 >/dev/null touch foobar gitNoFail add foobar gitNoFail commit -m second popd >/dev/null #create a repo intended as the server repo that all users clone from printHeader "setup server repo" createRepo server1 #add submodule pushd server1 >/dev/null gitNoFail ${gitArgs} submodule add -b master "${root}/child1" sub1 gitNoFail commit -m added_submodule popd >/dev/null #a user clones from server printHeader "setup user repo" gitNoFail ${gitArgs} clone --recurse-submodules server1 user1 #change a submodule url in an arbitrary branch. This branch would have been pushed to the server by another user. printHeader "switch submodule url" pushd server1 >/dev/null pwd gitNoFail checkout -b exper gitNoFail config --file=.gitmodules submodule.sub1.url "${root}/child2" gitNoFail ${gitArgs} submodule sync -- sub1 gitNoFail ${gitArgs} submodule update --remote -- sub1 gitNoFail add --all gitNoFail commit -m switch_submodule_url popd >/dev/null #now user will update pushd user1 >/dev/null printHeader "user updates" pwd #this will give an error, but shouldn't gitTry fetch #test again printHeader "try again" gitNoFail branch -r -D origin/exper gitTry fetch #test workaround printHeader "workaround" gitNoFail branch -r -D origin/exper gitNoFail config submodule.recurse false gitNoFail fetch popd >/dev/null } main $@