我们有两个独立的rails_app,foo/
和bar/
(有充分理由分开)。它们都依赖于common/
文件夹中的某些模型等,目前与foo
和bar
平行。
我们当前的svn设置使用svn:externals
来共享common/
。本周末我们想试试git。经过大量研究,似乎解决这个问题的“犹太教”方法是使用git submodule
。我们在将foo
,bar
,common
分成不同的存储库后将其工作,但随后实现了所有strings attached:
- 在提交父级之前始终提交子模块。
- 在推送子模块之前始终按下子模块。
- 确保子模块的HEAD在提交之前指向分支。 (如果您是bash用户,我建议使用git-completion将当前分支名称放在提示符中。)
- 切换分支或拉动更改后,始终运行'git submodule update'。
醇>
所有这些问题比add
,commit
,push
更复杂。我们正在寻找更简单的方法来在git中共享common
。 This guy似乎使用git subtree
扩展程序取得了成功,但与标准gitand不同,看起来仍然不那么简单。
鉴于我们的项目结构,这是我们能做的最好的吗?我对rails插件/引擎知之甚少,但这似乎是一种可能的RoR-ish方式来共享库。
提前致谢。
答案 0 :(得分:8)
我认为git子模块系统比svn有很大的优势:外部或符号链接(这也使它们更难以使用):为每个超级项目版本存储实际的子模块版本。因此,在破坏向后兼容性的子模块中进行更改是非常安全的:可以使用正确的子模块版本检出任何版本的超级项目,因为超级项目将包含对正确子模块代码的引用。您还可以维护子模块的两个分支(例如v1.0.x和v2.0.x),并在不同的项目中使用不同的分支而不会出现问题。
所以我认为使用子模块确实值得,即使它们有点复杂。 Git 1.7在这方面有一些重大改进,例如git status
现在表示子模块中未提交的修改,所以你可能不会忘记先提交子模块。一个好的GUI也可能是一个帮助(我有一个关于此的小型宠物项目,请参阅here)。
如果你真的不想关心子模块版本(你永远不会在公共代码中进行向后不兼容的更改),那么我也建议使用符号链接。虽然提交和获取并不比子模块容易得多......
答案 1 :(得分:6)
我倾向于选择符号链接到子模块。
1)在3个单独的回购中有foo
,bar
和公共代码(common
)。
2)在foo
的目录中,根据需要添加指向common
的符号链接。
$ cd foo $ ln -s /path/to/common lib/common
3)检查链接。
$ git add lib/common $ git commit
4)重复bar
这利用了git尊重符号链接并存储目标位置的事实(而不是跟随链接。)
当然,期望您始终对common
使用相同的目标路径。我通过不检查符号链接,并在每个项目中添加README.setup文件来解决这个问题,提醒我在初始化时添加必需的符号链接。拥有执行此类初始化的devsetup.sh
也很有用。
IMO,这比子模块更好处理。
答案 2 :(得分:5)
一个插件是完全可行的方式,如果你最终在两个以上的项目中使用它或对公众有用,可能值得努力使它成为一个宝石。
这是关于这个主题的好资源
http://nubyonrails.com/articles/the-complete-guide-to-rails-plugins-part-i
更重要的是......
http://nubyonrails.com/articles/the-complete-guide-to-rails-plugins-part-ii
最后,您将有三个git存储库,一个用于 foo ,一个用于 bar ,另一个用于插件。
然后在每个项目中将数据保存到您将能够做到
./script/plugin install --force git://github.com/path/to/plugin/repository
保持最新状态。
祝你好运!- 乔纳森
答案 3 :(得分:2)
自1.7.11以来,Git子树是GIT的一部分,我写了一篇关于在Rails应用程序之间共享代码的文章:http://igor-alexandrov.github.com/blog/2013/03/28/using-git-subtree-to-share-code-between-rails-applications
简而言之:是的git-subtree非常有用并且效果很好!
答案 4 :(得分:1)
如果你正在寻找一个插件,你也应该考虑制作一个宝石。它们在使用方面非常相似,但宝石往往更容易使用,支持依赖管理,并且更容易与社区共享/分发。
Railscast的Ryan Bates有一个关于制作宝石的精彩教程视频,你可以在这里找到:http://railscasts.com/episodes/135-making-a-gem
答案 5 :(得分:0)
您可以使用公共代码创建存储库并将其克隆两次。两个克隆都会成为foo和bar。您仍然可以在两个项目的单独分支中开发公共代码,并将该分支推送到公共代码存储库。要更新项目中的公共代码,您只需将公共分支合并到foo和bar的主分支中。
更新:您可以将其想象为具有三个分支的单个存储库:common,foo和bar。您将在公共分支中拥有公共代码,并仅将项目特定代码添加到foo或bar分支。现在你可以将这个存储库克隆两次作为foo和bar,并从它们中删除一个分支(来自bar存储库的branch foo和来自foo存储库的branch bar)。然后你将从第一个存储库中删除foo和bar。这将成为公共存储库。最终结果与上述结果相同。
答案 6 :(得分:0)
您可以做的最好的事情是为您的公共库甚至是gem创建一个插件,这样您就可以通过这种方式更新/分发它。