问题 Mercurial:保持2个分支同步但具有一定的持久性差异?


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

我打算用来执行此操作的工作流程如下:

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

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

此工作流程的缺点是,无论何时进行更改,您不仅必须将其提交到您进行更改的任何分支,还必须将其移植到其他分支。有没有更合理的方式来做我想要的事情,也许使用补丁?或者失败了,有没有办法让提交过程自动将变更集自动移植到另一个分支,这是一个好主意吗?


4114
2017-08-10 15:38


起源

虽然已经选择了史蒂夫L.的优秀建议,但我还是会选择下面给出答案,但我想指出,不管你最终如何做到这一点, transplant 扩展是一种特别糟糕的方法。移植执行导出然后导入,这为您的变更集提供了一个全新的散列/节点ID。如果每个变更集都会在开发和生产之间更改名称,那么您就需要找到解决问题的地方和位置的问题。制造 hg incoming 和 hg outgoing dev和prod之间无法使用是在寻找麻烦。 - Ry4an Brase


答案:


我可能会使用Mercurial Queues来做这样的事情。将主存储库保留为开发版本,并拥有 for-production 对生产进行必要更改的补丁。


5
2017-08-10 17:06



Mercurial队列扩展 mercurial.selenic.com/wiki/MqExtension Mercurial Queues Extention Tutorial mercurial.selenic.com/wiki/MqTutorial - Nathan Hartley


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

  1. 使用主机名在prod和devel之间切换。我们在设置文件的顶部进行了一次检查,查看SERVER_NAME环境变量。如果它是www.production.com,则它是prod DB,否则它会选择指定的或默认的dev / test / stage DB。
  2. 使用Mercurial,只需要一个包含dev的克隆和一个克隆的克隆,在dev中进行所有更改,并在部署时从dev到prod。在拉动之后,你将有两个头从一个共同的祖先分叉(最后部署)。一个头只有一个变更集,只包含dev和prod部署之间的差异,另一个将拥有所有新工作。将它们合并到prod clone中,选择冲突时的prod变化当然,你有一个可部署的设置,并准备在'dev'上做更多的工作。无需分支,移植或使用队列。只要你从未将prod设置中的变更集拉入'dev',从dev开始拉动它总是需要合并,如果它只是几行就没什么可做的了。

2
2017-08-11 01:30





我用本地设置解决了这个问题。

  1. 附加到settings.py:

    尝试:
    来自local_settings import *
    除了ImportError:
    通过
    

  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包含:
    <script type =“text / javascript”src =“blabla.js”> </ script>
    至:
    <script type =“text / javascript”src =“blabla {{JS_EXTENSION}}”> </ script>
  4. 创建一个寻找的更新后挂钩 *.raw.js 并生成 .mini.js (原始的缩小版本);
  5. .mini.js$ 到你的 .hgignore

2
2018-01-11 01:33



这种方法非常整洁。我喜欢JS_EXTENSION部分,完全符合我的要求并且立即有意义。 - markmuetz


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

  • settings.py 到.hgignore,将它保存在存储库之外。
  • 带上你的 settings.py 来自两个独立分支的文件并将它们移动到两个单独的文件中, settings-prod.py 和 settings-dev.py
  • 创建一个部署脚本,将相应的settings-X文件复制到settings.py,以便您可以部署任一方式。

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

如果您执行了类似的操作,则可以省去分支存储库的需要。


1
2017-08-10 16:30



我喜欢这种方法,因为它没有分支,事实上我已经使用了一个类似的。我没有制作2个设置文件,而是创建了一个设置目录 __init__.py 文件在其中添加我的设置文件,prod.py和dev.py(从这个博客中提取的想法:blog.haydon.id.au/2009/07/django-development-workflow.html)。然后只是符号链接正确的wsgi脚本。但不幸的是我需要更改一些模板,生产使用缩小版本的javascript和dev使用unminified,我不认为我可以做到这一点没有一些讨厌的符号。 - markmuetz


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

因此,如果您没有更改不同的文件,它会很有效。


1
2017-08-25 08:24