Git子模块:无法将子模块更新为早期版本

时间:2017-04-04 13:03:26

标签: git-submodules

我花了很多时间阅读和试用git子模块。但我真的放弃了。

我的问题:

我正在将git存储库克隆为子模块。所以,我做了

git submodule add -b master url localpath

存储库开始下载,并在.gitmodules文件中创建相应的条目。 git submodule status显示最新的提交。

到目前为止一切顺利。

在开发过程中,发现子模块中的HEAD提交有一个bug。因此,应该将提交从主服务器更改为某个提交ID。

所以,我更改了.gitmodule文件中的commit id(7 aplhanumeric)from branch = master

branch = <commitid> -> .gitmodule file

并且做了

git submodule update --remote

错误是

致命:需要一次修订

无法在子模块路径中找到当前的原点/修订

我也试过

 git submodule foreach git pull

这样它将提取提交ID,但它只是返回

输入name_of_the_submodule

已经是最新的。

有人可以帮助我吗?

P.S:我已经完成了很多教程和问答。因此,如果您想为此付出乐趣,请首先指出答案,我将删除此帖。

2 个答案:

答案 0 :(得分:1)

按照问题中的描述克隆了子模块后:

git submodule add -b master url localpath

然后你应该能够changedir到子模块:

cd localpath

进入子模块后,您可以使用任何git命令,它们只会影响子模块的repo。例如,您可以签出该神圣分支或修订版:

git checkout <branch|tag|hash>

或签出master分支中的倒数第二个修订版:

git checkout HEAD~1

然后changedir回到主要的git repo:

cd ..

git status应该会产生类似的结果:

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitmodules
    new file:   localpath

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   localpath (new commits)

然后只需将更改添加到您的子模块中:

git add localpath

并提交

git commit -m "Add submodule url to localpath with older working commit"

答案 1 :(得分:1)

经过一些研究后,我回答了我自己的问题,这可能对其他人有所帮助:

理解git子模块是一件很大的痛苦,但是一旦你得到它,一切都开始变得有意义了!

以下帖子显示:

  • 添加子模块并让其他人与您的子模块同步。
  • 更新子模块并让其他人与您的子模块同步。
  • 删除子模块并与子模块进行其他同步。
  • 更新已删除的子模块。

添加子模块

git submodule add -b

.gitmodules(name,path,url,branch)中的条目按

下载相应的子模块
git submodule update --init

这有三个重要的事情,前两个对用户是隐藏的:

  1. 使用额外条目(子模块)更新.git / config

  2. 以.git / modules下的裸体形式下载存储库。这意味着.git中有.git。

  3. 将.git / modules中的git子模块检出到父目录中。

  4. 现在,在第2天,提交子模块的提交者意识到他应该将子模块更改为其他提交而不是HEAD。所以,他会去他的本地存储库,然后进入子模块路径,然后通过简单地调用来检查他想要的提交

    git checkout <hash>
    cd <parent dir>
    git submodule status
    

    此时,git子模块状态仍然不显示新的哈希。只有在进行更改时才会显示新哈希。现在,提交者只需要暂存(添加),提交和推送更改,以便所有其他开发人员都可以看到它。

    更新添加的子模块

    在第3天,其他开发人员只需调用命令

    即可更新其存储库
    git pull # this is to get the latest commit of the parent git repository.
    git submodule update --force # update the submodule with latest hash
    

    基本上,这里的要点很简单:子模块直到并且除非被告知这样做才会做出反应。只是做git pull,不会更新git子模块。开发人员可以继续处理他们的本地子模块,而不是“永远”将它们同步到服务器上的子模块。子模块更新将在显式调用git submodule update命令时发生。

    删除子模块

    现在,在第4天,提交者决定完全删除git子模块。这里的步骤也不简单,因为没有什么叫做git submodule rm应该已经等同于git submodule add了。这只能在仅遵循以下顺序的情况下完成:

    git submodule deinit submodulename
    
    1. 删除.git / config条目。

    2. 这会清除子模块目录!!在此命令之后,您将在submdoule目录中看不到任何内容。

    3. 但子模块的内容仍然可以在.git / modules下找到

    4. 因此,git状态-u仍会显示Everyting是最新的!

      所以显示删除,

      git rm submodulepath
      

      此时git status将返回.gitmodules已更改(子模块已被删除)并且子模块路径已被删除。提交并推动更改。

      使用已移除的子模块进行更新

      在第5天,开发人员希望“自动”删除子模块,就像使用git子模块更新一样。所以他们首先做一个git pull,它成功地删除了git子模块的所有索引

       git submodule status # shows nothing
      

      但是.git / config仍然包含有效的子模块条目,子模块文件夹中包含其所有内容,而裸存储库位于.git /子模块下!没有删除它们的命令。所有这些都必须通过手动明确删除..(如果我错了请纠正我)