2017-04-04 166 views
1

我花了大量时间阅读和尝试git子模块。但我真的放弃了。Git Submodule:无法将子模块更新到较早版本

我的问题:

我克隆一个Git仓库的子模块。所以,我做

git submodule add -b master url localpath 

存储库开始下载并在.gitmodules文件中进行相应的条目。 git子模块状态显示最新的提交。

到目前为止这么好。

在开发过程中,发现子模块中的HEAD提交有一个bug。所以,提交应该从主更改为一些提交ID。

所以,我在.gitmodule文件更改提交ID(7 aplhanumeric)从分支=主

branch = <commitid> -> .gitmodule file 

,也

git submodule update --remote 

的错误是

致命的:需要单个修订版

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

我也试过

git submodule foreach git pull 

,这样它会拉动提交ID,但它只是与

进入name_of_the_submodule

返回

已经是最新的。

任何人都可以帮我吗?

P.S:我已经经历了很多教程和问题和答案。所以如果你想为了好玩而低估这个,那么请先指出一个答案,我会删除这篇文章。

回答

1

您已经克隆子模块后,在你的问题描述:

git submodule add -b master url localpath 

那么你应该能够changedir子模块:

cd localpath 

一旦辅助模块,你可以使用任何git命令,它们只会影响子模块的回购。例如,您可以检出该神圣的分支或修订版:

git checkout <branch|tag|hash> 

或签第二个到最后的主分支修订:

git checkout HEAD~1 

然后changedir回主混帐回购协议:

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" 
+0

明白了!有几个教程指的是用来改变你的.gitmodule文件。他们都失败了,因此混乱。最简单的方法是克隆整个分支(不管提交ID如何),然后在所需提交ID的子模块中执行git checkout,然后在父分支中执行git commit,然后推送。 – infoclogged

+0

还有一件事。其他已经下载完整代码(包括子模块)的开发人员需要调用git pull,然后调用git submodule update或git submodule update --remote以与最新的子模块更改同步。 – infoclogged

+0

是的,每次更改子模块引用时,在父回购库上执行'git pull'时,子模块将显示为'modified'。要将子模块更新为新引用,只需在主要的回购库上运行'git submodule update'即可。 –

0

我回答我的问题,研究一点点后,可能会有所帮助给其他人:

理解git子模块是一件很痛苦的事情,但一旦你明白了,一切都开始有意义了!

以下后显示:

  • 添加子模块,让别人用你的子模块同步。
  • 更新子模块并让其他人与您的子模块同步。
  • 删除子模块并让其他子模块同步。
  • 更新已移除的子模块。

添加子模块

git的子模块添加-b

在.gitmodules(名称,路径,网址,分支)下载由

git submodule update --init 

这各子模块的入口有三个重要的事情,其中​​前两个对用户隐藏:

  1. 更新的.git /配置一个额外的条目(子模块)

  2. 下载下的.git /模块裸形式的储存库。这意味着,.git中有.git。

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

,第2天,在commiter,谁COMMITED子模块实现,他应该改变子模块其他一些承诺,而不是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拉,不会更新git子模块。开发人员可以继续在本地子模块上工作,而不会将其同步到“永久”服务器上。子模块更新会在显式调用git子模块更新命令时发生。

删除子模块

现在,在第四天的提交者,决定彻底删除git的子模块。这里的步骤也不简单,因为没有任何东西叫做git submodule rm,它应该已经相当于git submodule add。这只能做且仅当下面的顺序如下:

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

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

  3. 但是,子模块的内容仍在git的可用/模块

因此混帐状态-u这里仍然会显示Everyting是高达日期!

所以显示清除,

git rm submodulepath 

此时git的状态将返回.gitmodules已经改变(子模块已被删除)和子模块路径已被删除。提交并推送更改。

去掉子模块

在第五天更新,开发商要删除的子模块“自动”喜欢用git子模块的更新一样。所以他们先做一个混帐拉,这成功地删除所有指标到GIT子模块

git submodule status # shows nothing 

,但.git的/ config中仍然包含有效的子模块条目和子模块文件夹有与它的所有内容和纯仓库在.git/submodules下!没有命令可以删除它们。所有这些都必须通过手工明确删除。(请纠正我,如果我错了)