将git管理的子目录切换到子模块
我们曾经在Rails应用程序中对delayed_job进行了本地破解,位于vendor/plugins/delayed_job中。它作为一次性事件安装并签入主应用程序存储库中的 git。
现在我们决定在github上分叉delayed_job并用git子模块替换子目录,如下所述:
http://doblock.com/articles/using-git-submodules-to-manage-plugins-in-rails
在此之前,我只是删除了vendor/plugins/delayed_job,而没有现在,尽管添加了子模块,主存储库中的 git status 仍然在供应商/插件/delayed_job 中显示新文件。
我们应该如何处理作为存储库一部分的子目录被删除并用于保存 git 子模块的情况?在将子模块克隆到其位置之前,我们是否应该首先使用 git rm 删除它,或者更彻底地删除它?
We used to have a local hack of delayed_job in a Rails app, in vendor/plugins/delayed_job. It was installed as a one-time event and checked into git in the main app repo.
Now we decided to fork delayed_job on github and replace the subdirectory by a git submodule, as described e.g. here:
http://doblock.com/articles/using-git-submodules-to-manage-plugins-in-rails
Before doing that, I simply removed vendor/plugins/delayed_job, without checking it in. Now, despite adding the submodule, git status in the main repo still shows new files in vendor/plugins/delayed_job.
How should we handle the situation where a subdirectory which was a part of the repo is deleted and made to hold a git submodule? Should we first delete it with git rm, or obliterate it even more thoroughly, before cloning a submodule into its place?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
假设您不关心工作树中
vendor/plugins/delayed_job
的当前内容(即,将作为子模块检出的内容已经是工作树中内容的合适替代品)树),将目录转换为子模块的正常过程如下所示:当然,GitHub 存储库 URL 可能会有所不同;例如,您可能想要使用 HTTP URL 而不是上面的 SSH URL。
但是,你似乎做了一些不同的事情。据我所知,您做了这样的事情:
此过程有两个缺陷:
rm
将旧文件保留在您的 Git 索引中。假设您没有在
vendor/plugins/delayed_job
中有意进行任何更改(您可能没有,因为您正在用子模块替换它),您可以使用以下命令清理这种情况:从索引中取出所有
vendor/plugins/delayed_job
条目应该可以解决您的“仍然显示新文件”问题。使用 git submodule add 将创建 .gitmodules 文件,该文件将“子存储库”变成真正的子模块。Assuming that you do not care about the current contents of
vendor/plugins/delayed_job
in your working tree (i.e. the content that will be checked out as a submodule is already a suitable replacement for the content in your working tree), the normal procedure for converting a directory into a submodule looks like this:Of course, the GitHub repository URL may vary; for example, you may want to use an HTTP URL instead of the above SSH URL.
But, it seems like you did something a bit different. As best I can tell, you did something like this:
There are two flaws with this procedure:
rm
leaves the old files in your Git index.Assuming that you do not have any intentionally staged changes in
vendor/plugins/delayed_job
(you probably do not, since you are replacing it with a submodule), you can clean up the situation with these commands:Cleaning out all the
vendor/plugins/delayed_job
entries from the index should fix your “still shows new files” problem. Usinggit submodule add
will create the.gitmodules
file which turns the “subrepository” into a true submodule.我绝对不建议这样做。你将会有很多后果,因为 git 不知道当目录将类型更改为子模块时该怎么做。删除旧文件夹,然后使用不同的名称创建一个新文件夹,这将是一个明显更好的主意。
我们有一个被很多人(50+)使用的存储库,并决定从文件夹中创建一个子模块。为了不必更改某些构建脚本等,我们进行了上述更改。但这让 git 抓狂了,所以如果不先删除文件夹并做其他废话,就无法切换到每个旧分支(子模块更改前),与旧分支合并极其困难,最糟糕的是我们的自动构建系统,这是分布在多台机器上,完全损坏,无法像个人用户那样手动解决。
所以。只是不要这样做。 Git 绝对不会优雅地处理它。
I absolutely WOULD NOT RECOMMENDED DOING THIS. You're going to have a lot of fallout since git doesn't know what to do when a directory changes types into a submodule. It would be a significantly better idea to remove the old folder, then make a new one with a different name.
We have a repo used by many people (50+) and decided to make a submodule out of a folder. In order to not have to change some build scripts and the like we did the above change. But this makes git freak out, and so every old branch (pre submodule change) cannot be switched to without first deleting the folder and doing other nonsense, merges with old branches are extremely difficult, and worst of all our automated build system, which is distributed across several machines, totally broke and cannot be manually resolved like individual users can.
So. Just don't do it. Git absolutely does not handle it gracefully.