【问题标题】:How to add already cloned projects as submodules?如何将已克隆的项目添加为子模块?
【发布时间】:2013-05-23 22:44:09
【问题描述】:

我在一个文件夹中有大量我克隆了很长时间的项目;最近我将整个文件夹移到了我的一个仓库中,并希望将这些克隆的项目转换为子模块,以便将来更好地更新和控制。我在谷歌上搜索了很多关于如何做到这一点,但所有的教程都只讨论如何添加新的子模块。谁能帮帮我?

【问题讨论】:

    标签: git git-submodules


    【解决方案1】:

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

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

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

    编辑

    以下是我用来尝试重现 cmets 中提到的错误的内容。我检查了三次命令,但我仍然看不到错误:

    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
    

    使用以下命令检查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
    

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

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

    【讨论】:

    • 它看起来确实是正确的解决方案。昨晚我很着急,最后决定删除并重新添加所有存储库。不过还是谢谢你的回答!虽然我想知道是否有任何方式不需要输入 URL(远程 URL 应该存在于现有仓库中的某个地方,只是不知道如何提取它..)
    • 我收到“索引中已存在”错误。 @lynnard您在检查答案之前是否对其进行了测试?如果不是,那么我敦促您这样做,因为这具有误导性
    • @lynnard 我实际上解决了这个问题,并建议进行编辑。干杯!
    • @MuhsinFatih,您收到“索引中已存在”错误,因为您没有按原样遵循说明,您必须在添加子存储库之前将它们作为普通目录添加到主存储库作为子模块,在这种情况下,它们不会被视为子模块。顺便说一句,编辑被拒绝,因为这不是答案的一部分,而是应该了解submodule 命令或一般的 git。
    • @neevek 但这不是 OP 所要求的。他说他已经有一个 git 存储库,其中包含其他难以再次下载的 git 存储库。此外,由于我在第 2 步中说“已经克隆了存储库”,如果一个人没有,他们可以简单地跳过这一步。此外,您的陈述:“将现有的 git 存储库添加为子模块与添加新的相同”是不正确的,并且与您的评论冲突;您想在存储库中添加“现有 git 存储库”作为子模块,还是要将“新获取存储库”添加为子模块?
    【解决方案2】:

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

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

      git rm --cached ./localrepo
      
    2. 使用git submodule add https//example.com/remoterepo ./localrepo,其中./localrepo 是您现有的git 存储库。

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

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

    【讨论】:

    • git rm --cached ./localrepo 这在其他答案中对我来说是缺失的。否则我得到'<rep>' already exists in the index
    【解决方案3】:

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

    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
    

    明显的限制我没有费心去解决:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-05
      • 1970-01-01
      • 2022-01-03
      相关资源
      最近更新 更多