【问题标题】:Mercurial: keep 2 branches in sync but with certain persistent differences?Mercurial:保持 2 个分支同步但存在某些持续差异?
【发布时间】:2009-08-10 15:38:49
【问题描述】:

我是一名使用 django 独立工作的网络开发人员,我正在努力了解如何最好地使用 mercurial 部署网站。我想要的是能够保留一个可用于生产和开发工作的存储库。生产/开发之间总会有一些差异(例如,他们可能使用不同的数据库,开发总是会打开调试),但总的来说它们是同步的。我还希望能够直接在生产服务器上进行更改(整理 html 或 css,简单的错误修复等)。

我打算使用的工作流程如下:

  • 创建 2 个分支,prod 和 dev(所有设置最初设置为生产设置)
  • 在 dev 分支中更改 settings.py 和其他一些内容。所以现在我有 2 个头,从现在开始,存储库将永远有 2 个头。
  • (在开发机器上)对开发进行更改,然后使用“hg 移植”将相关变更集复制到生产环境。
  • 推送到主存储库
  • (在生产服务器上)从主仓库拉取,更新到产品头

注意:只要将更改移植到 dev 中,您也可以直接对 prod 进行更改。

此工作流程的缺点是,每当您进行更改时,您不仅必须将其提交到您进行更改的任何分支,还必须将其移植到另一个分支。有没有更明智的方式来做我想做的事,也许是使用补丁?或者如果做不到这一点,有没有办法自动化提交过程以自动将变更集移植到另一个分支,这是一个好主意吗?

【问题讨论】:

  • 我会在下面给出一个答案,尽管 Steve L. 的优秀建议已经被选中,但我想指出,不管你最终如何做到这一点,transplant扩展是一种特别糟糕的方法。 Transplant 会先导出然后再导入,这会为您的变更集提供一个全新的哈希/节点 ID。如果每个变更集在开发和生产之间更改名称,您就会在跟踪问题在哪里和哪里引入问题时遇到麻烦。让 hg incominghg outgoing 在 dev 和 prod 之间无法使用是自找麻烦。

标签: django mercurial


【解决方案1】:

我可能会使用 Mercurial Queues 来完成类似的事情。将主存储库保留为开发版本,并拥有一个 for-production 补丁,用于对生产进行任何必要的更改。

【讨论】:

【解决方案2】:

这里有两种可能的解决方案,一种使用 mercurial,另一种不使用 mercurial:

  1. 使用主机名在 prod 和 devel 之间切换。我们在设置文件的顶部有一个检查 SERVER_NAME 环境变量的检查。如果是 www.production.com,它是 prod 数据库,否则它会选择一个指定的或默认的 dev/test/stage 数据库。
  2. 使用 Mercurial,只需创建一个作为 dev 的克隆和一个作为 prod 的克隆,在 dev 中进行所有更改,并在部署时从 dev 拉取到 prod。拉动后,您将有 2 个头在与一个共同祖先(最后一次部署)不同的 prod 中。一个负责人将拥有一个变更集,其中仅包含 dev 和 prod 部署之间的差异,而另一个负责人将拥有所有新工作。将它们合并到 prod 克隆中,当然选择冲突时的 prod 更改,并且您已经有了一个可部署的设置,并准备在“开发”上做更多的工作。无需分支、移植或使用队列。只要您从不将带有 prod 设置的变更集拉到“开发”中,它在从开发中拉出后总是需要合并,如果它只是几行,那就没什么可做的了。

【讨论】:

    【解决方案3】:

    我已经通过本地设置解决了这个问题。

    1. 附加到 settings.py:

      try:
      from local_settings import *
      except ImportError:
      pass
      

    2. touch local_settings.py

    3. ^local_settings.py$ 添加到您的.hgignore

    我所做的每个部署都有自己的本地设置(通常是不同的数据库内容和不同的原始电子邮件地址)。

    PS:稍后只阅读“缩小版的 javascript 部分”。为此,我建议使用更新后挂钩和配置设置(如 JS_EXTENSION)。

    示例(来自我的脑海!未经测试,根据需要进行调整):

    1. 将 JS_EXTENSION = '.raw.js' 放入您的 settings.py 文件中;
    2. 将 JS_EXTENSION = '.mini.js' 放入生产服务器上的 local_settings.py 文件中;
    3. 从以下位置更改 JS 包含: <pre>&lt;script type="text/javascript" src="blabla.js"&gt;&lt;/script&gt;</pre> 到: <pre>&lt;script type="text/javascript" src="blabla{{JS_EXTENSION}}"&gt;&lt;/script&gt;</pre>
    4. 制作一个更新后挂钩,查找 *.raw.js 并生成 .mini.js(原始的缩小版本);
    5. .mini.js$ 添加到您的.hgignore

    【讨论】:

    • 这个方法很简洁。我喜欢 JS_EXTENSION 部分,完全按照我的意愿去做,并且立即有意义。
    【解决方案4】:

    也许可以尝试这样的事情:(我只是在考虑这个问题,在我的情况下它是一个 sqlite 数据库)

    • settings.py 添加到 .hgignore,使其远离存储库。
    • 从两个单独的分支中取出您的 settings.py 文件并将它们移动到两个单独的文件中,settings-prod.pysettings-dev.py
    • 创建一个部署脚本,将相应的 settings-X 文件复制到 settings.py,这样您就可以采用任何一种方式进行部署。

    如果您有几个附加文件,请对它们执行相同的操作。如果您有很多文件,但它们自己都在同一个目录中,您可以创建一对目录:productiondevelopment,然后将相应的文件复制或符号链接到 deploy目录。

    如果你做了这样的事情,你可以免除分支你的存储库的需要。

    【讨论】:

    • 我喜欢这种方法,因为它没有分支,实际上我已经使用了类似的方法。我没有创建 2 个设置文件,而是创建了一个设置目录并在其中放置了一个 __init__.py 文件,并在其中添加了我的设置文件 prod.py 和 dev.py(来自此博客的想法:blog.haydon.id.au/2009/07/django-development-workflow.html)。然后只需符号链接正确的 wsgi 脚本。但不幸的是,我还需要更改一些模板,生产使用 javascript 的缩小版本,而开发使用未缩小的,我认为如果没有一些讨厌的符号链接,我无法做到这一点。
    【解决方案5】:

    我实际上是使用命名分支和直接合并而不是移植(更可靠,IMO)来做到这一点。这通常有效,但有时(当您在另一个分支上编辑了不同的文件时),您需要注意不要在合并时再次删除差异。

    因此,如果您不太多更改不同的文件,它会非常有用。

    【讨论】:

      猜你喜欢
      • 2013-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-19
      • 2017-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多