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 $@