我在最近的一个项目中使用 Mercurial。在我部署项目的 Web 服务器上,我的配置文件与生产设置略有不同。问题是当我pull
和时update
,我经常不得不merge
和commit
。
这是正确的工作流程吗?奇怪的是,为了能够继续更新,我必须提交变更集,我认为合并会将它们集成到我的生产分支中,并在每次更新时继续这样做。这是我还不习惯的分布式版本控制范例吗?
一种选择是将特定于服务器的部署设置完全排除在版本控制存储库之外。
这意味着上传它们并在服务器上手动更改它们,但无需不断合并。它还使诸如数据库密码之类的东西不受版本控制,这可能是一件好事。
例如,当我处理 Django 应用程序时,我签入一个settings.py
包含以下内容的文件:
from deploy import *
。如果存在,则该from deploy import *
行会拉入文件中的所有项目。deploy.py
在测试/登台/生产服务器上,我将创建此文件并将特定于服务器的设置放入其中。因为导入发生在这些操作的末尾,settings.py
所以会覆盖主设置文件中的任何本地开发特定设置。
这样做意味着在本地运行和开发所需的一切都被签入版本控制,但不会签入特定于服务器和/或敏感信息(如密码)(因此永远不需要合并)。它需要一些额外的工作来设置(添加导入行并deploy.py
最初在服务器上创建文件)。
此特定方案适用于 Django 项目,但也许类似的想法对您有用。
这是在这个问题中处理的,但我认为你的问题更好,因为它寻求更清晰。
简而言之:是的,这很正常。这里有一点扩展:
您从主存储库中开始(其中的框是变更集):
main: --[E]--[F]--[G]
然后您克隆到生产服务器并添加一个变更集 H,它执行部署自定义。所以部署 repo 看起来像这样:
production: --[E]--[F]--[G]--[H]
然后在主仓库上进行更多工作,添加变更集 I 和 J,使主仓库看起来像:
main: --[E]--[F]--[G]--[I]--[J]
当拉到生产时看起来像:
production: --[E]--[F]--[G]--[I]--[J]
\
\-[H]
有两个头,你合并得到:
production: --[E]--[F]--[G]--[I]--[J]
\ \
\-[H]-----[K]
其中 K 只是 J 加上您最初在 H 中所做的更改。
现在更多的工作发生在 main 中,给出:
main: --[E]--[F]--[G]--[I]--[J]--[L]--[M]
您在生产中提供的内容:
production: --[E]--[F]--[G]--[I]--[J]--[L]--[M]
\ \
\-[H]-----[K]
然后你合并并得到:
production: --[E]--[F]--[G]--[I]--[J]--[L]--[M]
\ \ \
\-[H]-----[K]-------[N]
因此,每次您从 main 引入更改时,您都会进行一次合并,并创建一个新的变更集(这次是 N)。
我认为这没关系,而且是“正常的”。
但是,您可以通过使用我上面链接的问题中的一些答案来避免它,并且您可以使用一个新技巧来不断修改原始 H 的父母(和内容),以便它始终移动到任何内容的末尾新的提示。
诀窍是Rebase 扩展,它会在生产中产生线性历史(尽管你仍然会做本质上是合并来获得它的事情)。我不喜欢它,因为我不喜欢在它们提交后更改变更集,但由于 H 永远不会离开生产框,所以没关系。
其他答案是反复无常的队列,并使生产更改在开发存储库中生效,并由生产环境中不同的东西触发(例如 Host: 标头)。