如何将已经克隆的项目添加为子模块?

lyn*_*ard 7 git git-submodules

我在一个文件夹中有大量克隆了一段时间的项目。最近,我将整个文件夹移到了我的仓库中,希望将这些克隆的项目转换为子模块,以便将来更好地进行更新和控制。我已经在Google上搜索了很多有关如何执行此操作的方法,但是所有教程仅讨论如何新鲜添加子模块。有人可以帮助我吗?

nee*_*vek 9

将现有的git存储库添加为子模块与添加新的git模块相同。

  1. 首先,将包含所有git存储库本身的文件夹作为git存储库git init
  2. 使用git submodule add https//example.com/remoterepo ./localrepo./localrepo您现有的git仓库在哪里。
    • 注意:你得到的URL remoterepolocalrepo/.git/config
  3. 对要添加为子模块的所有现有存储库重复第二步。
  4. 现在,您可以运行git submodule foreach git pull以更新所有子项目。

如果您有很多子模块,您可能需要编写一个小的脚本来自动化第二步,这并不难。

编辑

以下是我用来尝试重现注释中提到的错误的方法。我对命令进行了三重检查,但仍然看不到错误:

git --version

mkdir submoduletest
cd submoduletest

git init --bare remote_repo_A
git init --bare remote_repo_B 

git clone remote_repo_A local_repo_A
git clone remote_repo_B local_repo_B

cd local_repo_A
echo "test commit on repo B" >> test.txt
git add test.txt
git commit -m 'test commit message'
git push origin master

cd ../local_repo_B
echo "test commit on repo B" >> test.txt
git add test.txt
git commit -m 'test commit message'
git push origin master

cd ../local_repo_A
git clone ../remote_repo_B local_repo_B
git submodule add ../remote_repo_B ./local_repo_B
git submodule foreach git pull origin master

git add .
git ci -m 'we just added a submodule for remote_repo_B'

git submodule status
Run Code Online (Sandbox Code Playgroud)

使用下面的命令检查的当前状态local_repo_A,它只有两个BLOB对象,一个“test.txt的”,另一个是隐式创建” .gitmodules'文件,没有从remote_repo_B被添加到索引local_repo_A

find .git/objects -type f | awk -F/ '{print $3$4}' | xargs -I {} git cat-file -t {} | grep blob
Run Code Online (Sandbox Code Playgroud)

我回滚编辑的原因是因为编辑只是错误,它已经被其他两个调解人和我拒绝,但是后来其他人批准了它,我不确定这是SO的错误还是什么。但是编辑还是被拒绝了,即使是现在,因为它是完全错误的,我已经在评论中解释了为什么我不冒犯任何人,但是这浪费了我的时间,如果答案对您没有帮助,请否决它。

同样,如果您没有改善它,请不要编辑我的答案。


Muh*_*tih 8

我将添加到@neevek的答案,如果你收到错误already exists in the index,那么你可以尝试这个版本:

  1. 从缓存中删除每个“已克隆的存储库” :(
    因为那里已经有一个对象不作为子模块指向存储库,并且必须首先从索引中删除它以防止冲突。您的存储库的内容或索引将不会执行此操作后将被删除)

    git rm --cached ./localrepo
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用git submodule add https//example.com/remoterepo ./localrepo./localrepo您现有的 git 存储库在哪里。

    • remoterepo注意:您可以从获取 URL localrepo/.git/config
  3. 对要添加为子模块的所有现有存储库重复第二步。
  4. 现在您可以运行git submodule foreach git pull来更新所有子项目。

如果您有很多子模块,您可能需要编写一个小脚本来自动执行第二步。


DuB*_*sch 6

为了添加许多子模块,我写了这个简单的循环:

for repo in vim/bundle/*
do
  echo $repo
  pushd $repo
  url=$(git remote get-url $(git remote))
  echo $url
  popd
  git submodule add $url ./$repo
done
Run Code Online (Sandbox Code Playgroud)

我没有费心修复的明显限制:

  • 不需要更改目录,很确定您可以将 git 目录作为参数传递给命令
  • git remote 实际上返回所有遥控器,而不仅仅是当前的,所以如果有多个,脚本会中断