git detached head in source cause' git submodule update'失败与致命:需要一次修改'

时间:2017-09-30 23:34:09

标签: git

这是一个用于重建此问题的测试bash脚本,git --version说" git版本1.9.1"。基本上,我有一个"源子模块" repo /tmp/TestSubber,我在一个"源超级项目"中用作子模块。 /tmp/TestMain repo - 以及我想克隆的来源"本地"如/tmp/TestLocMain,并在克隆中初始化子模块:

set -x

rm -rfv /tmp/TestSubber /tmp/TestMain /tmp/TestLocMain
mkdir /tmp/TestSubber /tmp/TestMain
cd /tmp/TestSubber; git init;
git config user.name me; git config user.name me@example.com;
echo "aaaa" >> a.txt ; git add a.txt; git commit -m 'commit 01'
echo "aaaa" >> a.txt ; git add a.txt; git commit -m 'commit 02'
echo "aaaa" >> a.txt ; git add a.txt; git commit -m 'commit 03'
echo "aaaa" >> a.txt ; git add a.txt; git commit -m 'commit 04'
git checkout HEAD~2
git status # HEAD detached at f221985

cd /tmp/TestMain; git init;
git config user.name me; git config user.name me@example.com;
echo "bbbb" >> b.txt ; git add b.txt; git commit -m 'commit 01'
git submodule add -b master --depth 1 -- https://github.com/rtyley/small-test-repo TestSubber
git add -u; git commit -m 'added submodule'

cd /tmp
git clone file:///tmp/TestMain /tmp/TestLocMain
cd TestLocMain
sed -i"" 's!https://github.com/rtyley/small-test-repo!file:///tmp/TestSubber!g' .gitmodules
git submodule sync
git submodule update --init --remote --depth 1 --merge -- TestSubber

运行此脚本时,git submodule update的最后一步将失败:

...
+ git submodule update --init --remote --depth 1 --merge -- TestSubber
Submodule 'TestSubber' (file:///tmp/TestSubber) registered for path 'TestSubber'
Cloning into 'TestSubber'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
Checking connectivity... done.
From file:///tmp/TestSubber
 * branch            HEAD       -> FETCH_HEAD
fatal: Needed a single revision
Unable to find current origin/master revision in submodule path 'TestSubber'

看起来问题是源子模块repo git checkout HEAD~2中的/tmp/TestSubber,它强制该repo处于分离的HEAD状态;如果您对该行git checkout HEAD~2发表评论,那么最后的步骤将成功:

...
+ git submodule update --init --remote --depth 1 --merge -- TestSubber
Submodule 'TestSubber' (file:///tmp/TestSubber) registered for path 'TestSubber'
Cloning into 'TestSubber'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
Checking connectivity... done.
Submodule path 'TestSubber': checked out 'ad110f4932339fe5efb940608139b08a28b8c518'

现在,我的实际用例是与TestSubber对应的内容很大,并且需要暂时保持在分离的HEAD状态。我可以做些什么来强制TestLocMain中的子模块更新成功完成,而不更改TestSubber的状态?

1 个答案:

答案 0 :(得分:0)

好吧,看起来我得到了它 - 基本上,我需要重建/tmp/TestLocMain/.git/modules/TestSubber作为一个裸回购,然后用它作为GIT_DIR进行git pull,并将/tmp/TestLocMain/TestSubber作为GIT_WORK_TREE,然后最后发布git submodule update...命令(现在不需要--merge或任何东西)。请注意,我添加了一代并添加了100MB文件,以测试git submodule update...命令是否也将执行完整检出(显然,它没有):

set -x

rm -rfv /tmp/TestSubber /tmp/TestMain /tmp/TestLocMain
mkdir /tmp/TestSubber /tmp/TestMain
cd /tmp/TestSubber; git init;
git config user.name me; git config user.name me@example.com;
echo "aaaa" >> a.txt ; git add a.txt; git commit -m 'commit 01'
echo "aaaa" >> a.txt ; git add a.txt; git commit -m 'commit 02'
echo "aaaa" >> a.txt ; git add a.txt; git commit -m 'commit 03'
echo "aaaa" >> a.txt ; git add a.txt; git commit -m 'commit 04'
dd if=/dev/urandom of=big.file bs=1M count=100
git add big.file; git commit -m 'commit 05 big.file'
git checkout HEAD~2
git status # HEAD detached at f221985

cd /tmp/TestMain; git init;
git config user.name me; git config user.name me@example.com;
echo "bbbb" >> b.txt ; git add b.txt; git commit -m 'commit 01'
git submodule add -b master --depth 1 -- https://github.com/rtyley/small-test-repo TestSubber
git add -u; git commit -m 'added submodule'

cd /tmp
git clone file:///tmp/TestMain /tmp/TestLocMain
cd TestLocMain
sed -i"" 's!https://github.com/rtyley/small-test-repo!file:///tmp/TestSubber!g' .gitmodules
git submodule sync
mkdir -p .git/modules/TestSubber
MODDIR="`cd .git/modules/TestSubber && pwd`"
GIT_DIR="$MODDIR" git init --bare
GIT_DIR="$MODDIR" git config core.bare false
GIT_DIR="$MODDIR" git remote add origin file:///tmp/TestSubber
cd /tmp/TestLocMain
echo 'gitdir: ../.git/modules/TestSubber' > TestSubber/.git
GIT_DIR="$MODDIR" GIT_WORK_TREE="/tmp/TestLocMain/TestSubber" git pull --depth=1 origin master

git submodule update --init --remote --depth 1 -- TestSubber
git submodule status