作为 Visual Studio 解决方案中的外部项目工作者,我希望分享一下自己解决类似问题的经验。我对 Git 相对较新,如果有人能提供建设性的批评意见,我将不胜感激。
如果你在使用 Visual Studio,Git 源代码控制提供程序扩展是免费的(http://visualstudiogallery.msdn.microsoft.com/63a7e40d-4d71-4fbb-a23b-d262124b8f4c),而且测试时似乎会递归提交子模块。
但是,我在家里开发时使用的是 VS Web Developer Express,所以我不想依赖扩展程序(我也认为了解底层发生的事情是很重要的)。因此,我被迫研究这些命令,并在下面添加了一些注释。
注释
如果您还没有这样做,请仔细阅读http://git-scm.com/book/en/Git-Tools-Submodules。有很多注意事项,我会参考这个页面。如果您在没有阅读此页的情况下使用子模块进行工作,您很快就会让自己头痛。
我的方法遵循这篇教程,并添加了一些额外的内容:
一旦您初始化了超级项目(例如 git init
&& git remote add origin ...
),就可以像这样开始添加子模块:
git submodule add git://github.com/you/extension1.git extension
git submodule init
git submodule update
检查您的.gitmodules文件是否反映了此添加,例如:
[submodule "extension1"]
path = extension
url = git://github.com/you/extension1.git
进入子模块目录(即 cd extension
)。运行:
Switch to your submodule directory (i.e. cd extension
). Run:
git fetch #I use fetch here - maybe you can use pull?
git checkout -b somebranchname #See the Git-Tools-Submodules link above for an explanation of why you need to branch
我在 README.txt 文件中做了修改,以便提交它(也为了记录我在此次提交中所做的工作),然后将模块提交以应用该分支(仍在子模块目录中):
git add .
git commit -a -m "Branching for extension submodule"
现在进入超级项目(即 cd ..
)。您还需要在此处进行提交(如果您查看我提到的git子模块页面,它会解释为什么这是必需的):
现在进入超级项目(即 cd ..
)。您还需要在此处提交更改(如果您查看我提到的git子模块页面,它会解释为什么这是必要的):
git status #will show you that your submodule has been modified
git commit -a -m "Commiting submodule changes from superproject"
现在,如果需要,我们可以递归地推送我们的项目,如下所示:
git push --recurse-submodules=on-demand
你需要按照上述步骤为所有子模块运行一次。
在为所有子模块完成此操作并开始进行更改以进行提交和推送后,您可以使用:
git submodule foreach 'git add .' #recursively add files in submodules
不幸的是,我还没有找到一种递归提交的方法,而不使用像git-slave
这样的工具(有人用过吗?),因此您需要进入每个子模块目录并对刚添加的文件运行常规提交。在超级项目中执行:
git status
cd extension
git commit -a -m "Commiting extension changes in superproject edit session"
一旦子模块提交了,您还需要再次提交超级项目:
所以执行以下操作:
cd ..
git add .
git commit -a -m "Altered extension submodule"
git status #should now show 'working directory clean', otherwise commit other submodules in the same manner
这可能会有点烦人(因为你最终需要提交两次),但一旦你意识到它,实际上并不那么糟糕(因为它强制你检查每个项目中的提交内容)。这只是我的意见 - 如果你已经将一些超级项目的功能隔离成子模块,那么它应该可以独立于其余项目工作(因此,尽管有点烦人,但在不同时间提交它们并不是世界末日)。
现在我们可以再次推送...
git push --recurse-submodules=on-demand
如果你进入子模块并再次尝试推送,你会发现它不会执行任何操作,因为最新提交已经被推送了。
对于超级项目的克隆(或使用远程源),可能也会非常令人困惑 - 例如需要在运行
git submodule init
之后两次运行
git submodule update
。阅读
http://git-scm.com/book/en/Git-Tools-Submodules中的“使用子模块克隆项目”一节。
在克隆我的超级项目时让我犯了一个错误,就是如何获取子模块的最新更改。参考
Easy way pull latest of all submodules。
我的变体是为已检出的子模块使用“开发”分支(但您可以将其命名为任何名称),然后在超级项目中使用它。
git submodule foreach git pull origin development
我设置这个时,还会切换到要提交更改的子模块所在的分支,方法如下:
cd extension
git checkout -b development
我可以确认,当我按照上述步骤进行操作时,在克隆/远程源项目中对子模块所做的更改(在推送时)会显示在同一项目的其他克隆/远程源中(不要忘记最后的子模块拉取命令)。
希望这对你有所帮助。
git submodule update
,那么子模块总是会执行分离 HEAD 检出。这是正常行为。如果随后你对该分离 HEAD 进行更改提交,那么在另一个git submodules update
之后,它将再次将分离 HEAD 分支重置为 在 那些提交之前。 - Carlo Wood