代码之家  ›  专栏  ›  技术社区  ›  jtgameover

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

  •  17
  • jtgameover  · 技术社区  · 16 年前

    我们有两个独立的rails\u应用程序, foo/ 和 bar/ (有充分理由分开)。它们都依赖于某些模型等 common/ 文件夹,当前平行于 foo 和 bar .

    我们当前的svn设置使用 svn:externals 分享 普通的/ . 本周末,我们想尝试git。经过大量研究,解决这一问题的“犹太”方法似乎是 git submodule . 我们分手后就开始工作了 foo公司 , 酒吧 , common 然后实现了所有 strings attached :

    1. 始终在提交父模块之前提交子模块。
    2. 在推送父模块之前,始终推送子模块。
    3. 在提交之前,确保子模块的头指向分支。(如果您是bash用户,我建议使用git补全在提示符中输入当前的分支名称。)
    4. 切换分支或拉取更改后,始终运行“git submodule update”。

    所有这些都让事情变得更加复杂 add , commit , push . 我们正在寻找更简单的分享方式 常见的 单位:git。 This guy 似乎已成功使用 git subtree 扩展,但这与标准Git不同,而且看起来仍然没有那么简单。

    鉴于我们的项目结构,这是我们能做的最好的吗?我对rails插件/引擎了解不够,但这似乎是共享库的一种可能的错误方式。

    提前谢谢。

    7 回复  |  直到 9 年前
        1
  •  8
  •   gyim    16 年前

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

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

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

        2
  •  6
  •   0xfe    16 年前

    我倾向于使用符号链接而不是子模块。

    1) 拥有 foo , bar ,以及通用代码( common )在3份单独的回购协议中。

    2) 在的目录中 foo公司 ,将符号链接添加到 常见的 ,如有必要。

    $ cd foo
    $ ln -s /path/to/common lib/common
    

    3) 签入链接。

    $ git add lib/common
    $ git commit
    

    4) 对重复 酒吧

    这利用了git尊重符号链接并存储目标位置(而不是遵循链接)这一事实

    当然,我们的期望是您始终使用相同的目标路径 常见的 . 我通过不签入符号链接并添加自述来解决这个问题。每个项目中的设置文件,提醒我在初始化时添加必要的符号链接。拥有 devsetup.sh 这样做,这种初始化在这里也很有用。

    依我看,这比处理子模块要好得多。

        3
  •  5
  •   Jonathan    16 年前

    插件是完全可行的,如果你最终在两个以上的项目上使用它,或者对公众有用,那么可能值得努力使其成为一个宝石。

    这里有一个关于这个主题的好资源

    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公司 ,一个用于 酒吧 还有一个是 插件 .

    然后在每个项目中,将其保持为您能够做到的数据

    ./script/plugin install --force git://github.com/path/to/plugin/repository

    使其保持最新。

    祝你好运

    --乔纳森

        4
  •  2
  •   Igor Alexandrov    13 年前

    Git子树是Git自1.7.11以来的一部分,我写了一篇关于在Rails应用程序之间共享代码的文章: http://igor-alexandrov.github.com/blog/2013/03/28/using-git-subtree-to-share-code-between-rails-applications

    简而言之:是的,git子树非常有效!

        5
  •  1
  •   Scott Swezey    16 年前

    如果你想制作一个插件,你也应该考虑制作一个gem。它们在使用上非常相似,但GEM往往更容易使用,支持依赖关系管理,更容易与社区共享/分发。

    Railscast的Ryan Bates有一段关于制作宝石的精彩教程视频,您可以在这里找到: http://railscasts.com/episodes/135-making-a-gem

        6
  •  0
  •   Tomas Markauskas    16 年前

    您可以使用公共代码创建一个存储库,并将其克隆两次。这两个克隆人都将成为foo和bar。您仍然可以在两个项目的不同分支中开发公共代码,并将该分支推送到公共代码存储库。要更新项目中的公共代码,只需将公共分支合并到foo和bar的主分支中。

    更新:您可以将其想象为一个具有三个分支的单一存储库:common、foo和bar。您将在公共分支中拥有公共代码,并将特定于项目的代码仅添加到foo或bar分支。现在,您可以将此存储库克隆为foo和bar的两倍,并从两者中删除一个分支(从bar存储库中删除分支foo,从foo存储库中删除分支bar)。然后从第一个存储库中删除foo和bar。这将成为公共存储库。最终结果与上述结果相同。

        7
  •  0
  •   thomasfedb    16 年前

    你能做的最好的事情就是为你的公共库创建一个插件,甚至是一个gem,这样你就有了一个很好的方法来更新/分发它。