如何在源代码控制中处理配置文件?

103

假设您有一个典型的Web应用程序,并且有一个名为configuration.whatever的文件。每个开发人员都会在他们的开发环境中使用一个版本,将会有一个dev,prod和stage版本。您如何在源代码控制中处理这个问题?是完全不提交此文件,还是以不同名称提交,或者采取其他花哨的方法?

19个回答

73

我过去的做法是准备一个默认的配置文件,将其纳入源代码控制。然后,每个开发者都有自己的覆盖配置文件,不包括在源代码控制中。应用首先加载默认配置文件,然后如果存在覆盖文件,则加载该文件并使用其中的任何设置替代默认文件。

一般来说,覆盖文件越小越好,但它始终可以为具有非常非标准环境的开发者包含更多设置。


24

配置是代码,你应该对其进行版本控制。我们的配置文件以用户名为基础,在UNIX/Mac和Windows中,你可以访问用户的登录名,并且只要这些对于项目是唯一的,你就没问题了。你甚至可以在环境中覆盖此设置,但你应该对所有内容进行版本控制。

这也允许你检查其他人的配置,这有助于诊断构建和平台问题。


10
非常赞同强调配置应该仍然进行版本控制。 - Alexander Bird
如果由于任何原因用户名不可靠,那么您可以有一个单独的文件,只有一行给出覆盖配置文件的名称。这样,几乎没有什么(大约10个字符左右)是不受版本控制的。README文件可以解释需要创建该文件。 - Alexander Bird
我一直认为配置应该与代码分开。我曾经在一些公司工作过,他们要求一个仓库有太多的配置文件,以至于Git无法处理这么多的配置文件。并不是说配置文件不应该进行版本控制,而是应该放在其他地方,比如构件管理器中。配置不是代码,它们只是代码的设置。 - Thomas
配置文件可能包含敏感信息,如密码,不应该被版本化。或者你想让每个开发人员都能访问你的生产环境吗?我认为最好只版本化一个“主配置文件”,并在特定环境中进行覆盖。 - Christophe Weis

19

不要对那个文件进行版本控制,可以对模板或其他内容进行版本控制。


2
我使用这种方法,我只有一个名为 main.php.tmpl 的文件,当我检出新的副本时,只需将其复制到 main.php。我将 main.php 文件添加到忽略列表中以避免意外提交它。 - levhita

10

我的团队针对每个环境保留单独的配置文件版本(web.config.dev、web.config.test、web.config.prod)。我们的部署脚本会复制正确的版本并将其重命名为web.config。这样,我们可以完全控制每个环境的配置文件版本,并且可以轻松执行差异比较等操作。


6

目前我有一个名为“template”的配置文件,其中添加了一个扩展名,例如:

web.config.rename

然而,如果发生重要更改,我认为这种方法存在问题。

6

+1 模板方法。

但是由于这个问题有Git标签,分布式替代方案就会浮现在脑海中,其中自定义内容被保留在私有测试分支上:

A---B---C---D---           <- mainline (public)
     \       \
      B'------D'---        <- testing (private)

在这个方案中,主线包含一个通用的“模板”配置文件,只需要最少的调整即可变得有效。现在,开发者/测试人员可以随心所欲地调整配置文件,并仅将这些更改提交到私有测试分支上(例如B'=B +自定义)。每次主线推进时,他们都可以轻松地将其合并到测试中,这会导致合并提交,如D'(= D + B的自定义版本的合并版本)。当“模板”配置文件更新时,这个方案真正发挥作用:双方的更改被合并,并且如果它们不兼容,则极有可能导致冲突(或测试失败)!

但是当开发人员和测试人员将代码推送到主干时,他们对模板文件所做的更改也会被推送进去,不是吗? - Nick Zalutskiy
除非有解决Nick评论的方案,否则从我看来这将无法正常工作。或者解释一下你正在使用哪种流模型来解决这个问题。 - Alexander Bird
我同意采用模板方法,并在构建时进行必要的调整。然而,在分支主题上...如果有多个模板(开发、测试等),开发人员只需从他们的提交中省略更改,这该怎么办呢?虽然不是绝对可靠的,但可以通过合作来解决。 - NickSuperb

5
我一直将所有版本的配置文件与web.config文件放在同一个文件夹中,并存入源代码管理系统。
例如:
web.config
web.qa.config
web.staging.config
web.production.config

我更喜欢这种命名约定(而不是web.config.production或production.web.config)因为

  • 当你按文件名排序时,它会让文件保持在一起
  • 当你按文件扩展名排序时,它会让文件保持在一起
  • 如果文件意外地被推送到生产环境,你将无法通过http查看内容,因为IIS将阻止*.config文件被提供

默认的配置文件应该被配置成这样,以便你可以在自己的机器上本地运行应用程序。

最重要的是,这些文件应该在每个方面都几乎完全相同,甚至格式也一样。你不应该在一个版本中使用制表符,在另一个版本中使用空格进行缩进。你应该能够运行一个diff工具来查看文件之间的区别。我更喜欢使用WinMerge来查看文件的不同之处。

当你的构建过程创建二进制文件时,应该有一个任务用适合该环境的配置文件覆盖web.config。如果这些文件被压缩,那么无关的文件应该从该构建中删除。


5
我们使用的解决方案是只有单一的配置文件(web.config/app.config),但我们在文件中添加了一个特殊的部分,其中包含所有环境的设置。
在我们的配置文件中,有LOCAL、DEV、QA和PRODUCTION等各个环境的配置键相关的部分。
让这一切正常工作的是一个名为xxx.Environment的程序集,它被引用于我们所有的应用程序(winforms和webforms)中,告诉应用程序它正在操作的环境。
xxx.Environment程序集从给定机器的machine.config中读取一行信息,告诉它它在DEV、QA等环境上。这个条目存在于我们所有的工作站和服务器上。
希望这能帮到您。

1
如果环境之间只有一些差异(例如连接字符串),那么这个方法非常有效。 - Eric Labashosky
假设没有数百名开发人员都将其自定义设置放在那里(它仍然可以工作,但非常繁琐)。 - Alexander Bird

4
我之前使用过模板,例如web.dev.config、web.prod.config等,但现在更喜欢使用“覆盖文件”技术。web.config文件包含大部分设置,但外部文件包含特定于环境的值,例如db连接。在Paul Wilson的博客上有很好的解释。
我认为这样可以减少配置文件之间的重复量,从而在添加新值/属性时减少痛苦。

3

@Grant是正确的。

我在一个拥有近100名开发人员的团队中,我们的配置文件没有被提交到源代码控制。我们在仓库中有文件的版本,每次检出时都会提取,但它们不会更改。

这对我们来说效果很好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接