作为在 Visual Studio 解决方案中使用外部项目尝试解决类似问题的人,我想与您分享我的经验。我对 git 比较陌生,所以如果有人有任何建设性的批评,我将不胜感激。
如果您使用 Visual Studio,Git Source Control Provider 扩展是免费的(http://visualstudiogallery.msdn.microsoft.com/63a7e40d-4d71-4fbb-a23b-d262124b8f4c),并且在我测试时似乎递归提交子模块出去。
但是我在家里使用 VS Web Developer Express 进行开发,所以我不想依赖扩展(我也认为了解幕后发生的事情是件好事)。因此,我被迫弄清楚命令,并在下面添加了一些注释。
笔记
如果您还没有完成,请彻底阅读http://git-scm.com/book/en/Git-Tools-Submodules。有很多警告,我将返回此页面。如果你试图在不阅读本文的情况下使用子模块,你很快就会让自己头疼。
我的方法遵循本教程,并添加了一些附加功能:http ://blog.endpoint.com/2010/04/git-submodule-workflow.html
一旦你初始化了你的超级项目(例如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
)。跑:
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 子模块页面,它解释了为什么这是必要的):
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 #tells you that `extension` submodule has been modified
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 update
在git submodule init
. 阅读http://git-scm.com/book/en/Git-Tools-Submodules的“使用子模块克隆项目”部分。
克隆我的超级项目时让我感到震惊的是获得子模块的最新更改。请参阅Easy way pull 最新的所有子模块
我的变体是为签出的子模块使用“开发”分支(但您可以随意调用它),然后在超级项目中使用它:
git submodule foreach git pull origin development
当我设置它时,我还交换到我想要将更改推送到已签出子模块的分支,如下所示:
cd extension
git checkout -b development #This will tell you this is a new branch, but I believe this means a new branch of the local git repository - this will get pushed to the 'development' branch
#Make your changes, commit etc.
我可以确认,当我按照上述步骤操作时,对克隆/远程源项目中子模块的更改(推送时)显示在同一项目的其他克隆/远程源中(不要忘记最后一个子模块拉取命令)。
我希望这对你有用。