在两个或多个rails应用程序之间共享代码... git子模块的替代方案?

时间:2010-04-19 17:26:55

标签: ruby-on-rails git git-submodules

我们有两个独立的rails_app,foo/bar/(有充分理由分开)。它们都依赖于common/文件夹中的某些模型等,目前与foobar平行。

我们当前的svn设置使用svn:externals来共享common/。本周末我们想试试git。经过大量研究,似乎解决这个问题的“犹太教”方法是使用git submodule。我们在将foobarcommon分成不同的存储库后将其工作,但随后实现了所有strings attached

  
      
  1. 在提交父级之前始终提交子模块。
  2.   
  3. 在推送子模块之前始终按下子模块。
  4.   
  5. 确保子模块的HEAD在提交之前指向分支。 (如果您是bash用户,我建议使用git-completion将当前分支名称放在提示符中。)
  6.   
  7. 切换分支或拉动更改后,始终运行'git submodule update'。
  8.   

所有这些问题比addcommitpush更复杂。我们正在寻找更简单的方法来在git中共享commonThis guy似乎使用git subtree扩展程序取得了成功,但与标准gitand不同,看起来仍然不那么简单。

鉴于我们的项目结构,这是我们能做的最好的吗?我对rails插件/引擎知之甚少,但这似乎是一种可能的RoR-ish方式来共享库。

提前致谢。

7 个答案:

答案 0 :(得分:8)

我认为git子模块系统比svn有很大的优势:外部或符号链接(这也使它们更难以使用):为每个超级项目版本存储实际的子模块版本。因此,在破坏向后兼容性的子模块中进行更改是非常安全的:可以使用正确的子模块版本检出任何版本的超级项目,因为超级项目将包含对正确子模块代码的引用。您还可以维护子模块的两个分支(例如v1.0.x和v2.0.x),并在不同的项目中使用不同的分支而不会出现问题。

所以我认为使用子模块确实值得,即使它们有点复杂。 Git 1.7在这方面有一些重大改进,例如git status现在表示子模块中未提交的修改,所以你可能不会忘记先提交子模块。一个好的GUI也可能是一个帮助(我有一个关于此的小型宠物项目,请参阅here)。

如果你真的不想关心子模块版本(你永远不会在公共代码中进行向后不兼容的更改),那么我也建议使用符号链接。虽然提交和获取并不比子模块容易得多......

答案 1 :(得分:6)

我倾向于选择符号链接到子模块。

1)在3个单独的回购中有foobar和公共代码(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创建一个插件,这样您就可以通过这种方式更新/分发它。