您如何处理源代码管理中的配置文件?


96

假设您有一个典型的Web应用程序,并且具有文件配置。每个从事该项目的开发人员都将为其开发箱提供一个版本,还将有一个开发,生产和阶段版本。您如何在源代码管理中处理此问题?根本不检入此文件,使用其他名称检查该文件还是一起做某事?

Answers:


69

我过去所做的是拥有一个默认配置文件,该文件已签入到源代码管理中。然后,每个开发人员都有自己的替代配置文件,该文件被从源代码管理中排除。该应用程序首先加载默认值,然后如果存在覆盖文件,则将其加载并使用从覆盖优先级到默认文件的任何设置。

通常,替代文件越小越好,但是对于具有非常非标准环境的开发人员,它始终可以包含更多设置。


24

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

这也使您可以检查其他人的配置,这可以帮助诊断构建和平台问题。


10
绝对+1,以强调仍应对配置进行版本控制
Alexander Bird

而且,如果用户名由于某种原因不可靠,那么您可以使用一个文件,仅一行给出覆盖配置文件的名称。通过这种方式,有非常小(在大约10个字符左右),这是不会受版本控制。README文件可以说明您需要制作该文件。
亚历山大·伯德

我一直认为配置应与代码分开。我在一个仓库中需要大量配置的地方工作,Git只是被配置文件所淹没。并不是说配置不应该被版本化,它们像工件管理器一样属于其他地方。Config不是代码,它们是代码设置。
托马斯

配置文件可能包含敏感信息,例如密码,不应进行版本控制。还是要授予每个开发人员访问您的生产环境的权限?我认为最好只发布一个“主配置”并在特定环境中覆盖它。
Christophe Weis

19

不要对该文件进行版本控制。版本化模板或其他内容。


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

10

我的团队为每个环境(web.config.dev,web.config.test,web.config.prod)保留不同版本的配置文件。我们的部署脚本会复制出正确的版本,并将其重命名为web.config。这样,我们对每种环境的配置文件都有完整的版本控制,可以轻松执行diff等。


6

当前,我具有添加了扩展名的“模板”配置文件,例如:

web.config.rename

但是,如果关键更改已更改,我会发现此方法存在问题。


6

+1模板方法。

但是由于这个问题带有标签Git,所以想到了分布式替代方案,其中自定义项保留在私有测试分支中:

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

在此方案中,主线包含一个通用的“模板”配置文件,该文件需要进行最少的调整才能起作用。

现在,开发人员/测试人员可以根据自己的意愿调整配置文件,并且仅在一个私有测试分支上本地提交这些更改(例如B'= B +定制)。每次主线前进时,他们都会毫不费力地将其合并到测试中,从而产生合并提交,例如D'(= D + B的自定义项的合并版本)。

当“模板”配置文件更新时,该方案确实非常出色:双方的更改被合并,并且如果不兼容,极有可能导致冲突(或测试失败)!


但是,当开发人员测试人员进入主线时,对模板文件的更改也将被推送。没有?
Nick Zalutskiy 09年

除非尼克的解决方案能够解决,否则从我看来这是行不通的。或者也许解释您正在使用哪种流程模型来解决问题。
亚历山大·伯德

我同意模板方法,并在构建时进行了必要的调整。但是,在分支主题上……如果存在多个模板(开发,测试等),并且开发人员只是忽略了提交内容的更改,该怎么办。并非万无一失,但可以合作。
NickSuperb 2011年

5

我们使用的解决方案是只有一个配置文件(web.config / app.config),但是我们在文件中添加了一个特殊部分,其中包含所有环境的设置。

本地,开发,质量检查,生产部分,每个部分都在我们的配置文件中包含与该环境相关的配置密钥。

使这一切正常进行的原因是一个名为xxx.Environment的程序集,该程序集在我们所有应用程序(winforms和webforms)中都被引用,它告诉应用程序在哪个环境中运行。

xxx.Environment程序集从给定计算机的machine.config中读取一行信息,告诉它它位于DEV,QA等上。我们所有的工作站和服务器上都存在此条目。

希望这可以帮助。


1
如果环境(即连接字符串)之间只有很少的差异,则此方法非常好
Eric Labashosky 09年

并假设没有数百个开发人员都将自定义设置也放在那里(它仍然可以工作,但是非常麻烦)
Alexander Bird

5

我一直将所有版本的配置文件保留在源代码管理中,与web.config文件位于同一文件夹中。

例如

web.config
web.qa.config
web.staging.config
web.production.config

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

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

应该配置默认配置文件,以便您可以在自己的计算机上本地运行该应用程序。

最重要的是,这些文件在各个方面都应几乎100%相同,即使是格式也一样。您不应在一个版本中使用制表符,而在另一个版本中使用空格进行缩进。您应该能够对文件运行差异工具,以查看它们之间的确切区别。我更喜欢使用WinMerge来区分文件。

当您的构建过程创建二进制文件时,应该有一个任务用适合该环境的配置文件覆盖web.config。如果压缩了文件,则应该从该版本中删除不相关的文件。


4

我以前使用过模板,即web.dev.config,web.prod.config等,但现在更喜欢“覆盖文件”技术。web.config文件包含大多数设置,但是外部文件包含特定于环境的值,例如db连接。保罗·威尔逊(Paul Wilson)博客上的精彩解释。

我认为这减少了配置文件之间重复的数量,这在添加新值/属性时可能会引起麻烦。


3

@格兰特是正确的。

我与其他将近100个开发人员组成一个团队,并且我们的配置文件未检入源代码管理。我们具有每次签出时都会拉出的存储库中文件的版本,但它们不会更改。

对我们来说效果很好。


2

我对它进行版本控制,但从不将其推送到其他服务器。如果生产服务器需要更改,则直接将更改更改为配置文件。

它可能不漂亮,但效果很好。


2

签入的普通版本的app / web.config应该足够通用,以在所有开发人员机器上都可以使用,并应保持最新状态,以进行任何新的设置更改等。如果您需要开发人员的一组特定设置/ test / production设置,如GateKiller所述,以某种命名约定检入带有这些设置的单独文件,尽管我通常使用“ web.prod.config”,以免更改文件扩展名。


2

我们使用已检入版本控制的模板配置文件,然后使用自动构建中的步骤将模板文件中的特定条目替换为特定于环境的设置。特定于环境的设置存储在单独的XML文件中,该文件也受版本控制。

我们在自动构建中使用MSBuild,因此我们使用MSBuild社区任务中的XmlUpdate 任务来更新值。


2

很长时间以来,我所做的正是bcwood所做的。我将web.dev.config,web.test.config,web.prod.config等的副本保留在源代码控制下,然后在构建/部署系统部署到各种环境时,它们会自动重命名它们。您在文件之间会得到一定程度的冗余(尤其是其中有所有的asp.net东西),但是通常它确实很好用。您还必须确保团队中的每个人都记得更新所有在进行更改时文件。

顺便说一句,我喜欢将“ .config”作为扩展名保留在末尾,以免文件关联被破坏。

至于配置文件的本地开发人员版本,我总是尽力鼓励人们尽可能使用相同的本地设置,以便不需要自己的版本。它并不总是对每个人都有效,在这种情况下,人们通常只是根据需要在本地更换它并从那里去。这不是太痛苦或什么。


1

在我们的项目中,我们将配置存储在带有前缀的文件中,然后我们的构建系统根据当前系统的主机名提取适当的配置。这对于一个相对较小的团队来说非常有效,如果/当我们添加新的配置项时,允许我们将配置更改应用于其他人的文件。显然,这绝对不能扩展到拥有无数开发人员的开源项目。


1

这里有两个问题。

  • 首先,我们必须控制软件随附的配置文件。

    如果开发人员在迁移环境中使用相同的文件,那么开发人员可以很容易地签入不需要的文件以更改主配置文件。

    另一方面,如果安装程序包含一个单独的配置文件,则很容易忘记为它添加新设置,或者让其中的注释与扩展中的注释不同步。配置文件。

  • 然后,我们面临的问题是,当其他开发人员添加新的配置设置时,开发人员必须将配置文件的副本保留在那里。但是,每个开发人员的某些设置(如数据库连接字符串)都不同。

  • 问题/答案未涵盖的第三个问题。 在安装新版本的软件时,如何合并客户对配置文件所做的更改?

我还没有看到在所有情况下都可以正常工作的好的解决方案,但是我看到了一些局部解决方案 (可以根据需要将其组合为不同的组合),从而大大减少了问题。

  • 首先,减少主配置文件中的配置项数量。

    如果您不需要让客户更改映射,请使用Fluent NHibernate(或其他方式)将配置移入代码。

    视情况注入设置也是如此。

  • 尽可能拆分配置文件,例如,使用单独的文件配置Log4Net日志。

  • 不要在很多配置文件之间重复项目,例如,如果您有4个Web应用程序都安装在同一台计算机上,则应具有一个整体配置文件,每个应用程序中的web.config文件都指向该配置文件。

    (默认情况下使用相对路径,因此很少需要更改web.config文件)

  • 处理开发配置文件以获取运输配置文件。

    可以通过在Xml注释中具有默认值来完成,然后在完成构建时在配置文件中设置默认值。或在创建安装程序的过程中删除部分。

  • 每个开发人员都有一个数据库连接字符串,而不仅仅是一个数据库连接字符串。

    例如,在运行时首先在配置文件中查找“ database_ianr”(其中ianr是我的用户名或计算机名),如果找不到,则查找“ database”

    使用第二级“例如-oracle或-sqlserver”可以使开发人员更快地访问两个数据库系统。

    对于任何其他配置值,当然也可以这样做。

    然后,可以删除所有以“ _userName”结尾的值,然后再发送配置文件。

但是,最后,您是“配置文件的所有者”,该负责任地以上述方式或其他方式管理配置文件。他/她还应该在每次装运之前对客户界面配置文件进行比较。

缺少这些问题,您无法消除对有爱心人士的需求。


1

我认为没有一个适用于所有情况的解决方案,因为它可能取决于配置文件中数据的敏感性,所使用的编程语言以及许多其他因素。但我认为将所有环境的配置文件置于源代码控制下非常重要,因此您始终可以知道何时更改了它以及由谁更改,更重要的是,如果出现问题,可以恢复它。他们会的。

所以这就是我的做法。通常这是针对nodejs项目的,但我认为它也适用于其他框架和语言。

我要做的是configs在项目的根目录下创建一个目录,并在该目录下为所有环境保留多个文件(有时还为每个开发人员环境保留单独的文件),这些文件均在源代码管理中进行跟踪。config在项目的根目录中有一个代码使用的实际文件。这是唯一未跟踪的文件。所以看起来像这样

root
|
|- config (not tracked)
|
|- configs/ (all tracked)
    |- development
    |- staging
    |- live
    |- James

当某人签出项目时,他将要使用的配置文件复制到未跟踪的文件中 config文件中,他可以根据自己的意愿随意编辑它,但是还可以在根据需要提交到其他环境文件之前复制这些更改。

在服务器上,未跟踪的文件可以只是与该环境相对应的跟踪文件的副本(或引用)。在JS中,您只需要一行即可要求该文件。

这种流程起初可能有点复杂,但是它具有很大的优势:1.您无需担心无需备份就可以在服务器上删除或修改配置文件的情况。2.如果开发人员在其上有一些自定义配置,也是如此机器及其机器因任何原因停止工作3.在进行任何部署之前,您可以区分config development和的配置文件staging,例如,查看是否有任何丢失或损坏的文件。


0

我们只是保持生产配置文件处于签入状态。开发人员有责任在安全地将其从源中拉出来以进行登台或开发时更改文件。过去这已经烧死了我们,所以我不建议这样做。


0

我遇到了同样的问题,并且找到了解决方案。我首先将所有文件添加到中央存储库(也包括开发人员的文件)。

因此,如果开发人员从存储库中获取文件,则开发人员配置也在那里。对此文件进行更改时,Git应该不知道这些更改。这样,更改不能被推送/提交到存储库,而是保留在本地。

我解决了这个使用Git的命令:update-index --assume-unchanged。我制作了一个bat文件,该文件在项目的预构建中执行,该项目包含一个文件,其更改应被Git忽略。这是我放入bat文件中的代码:

IF NOT EXIST %2%\.git GOTO NOGIT
set fileName=%1
set fileName=%fileName:\=/%
for /f "useback tokens=*" %%a in ('%fileName%') do set fileName=%%~a
set "gitUpdate=git update-index --assume-unchanged"
set parameter= "%gitUpdate% %fileName%"
echo %parameter% as parameter for git
"C:\Program Files (x86)\Git\bin\sh.exe" --login -i -c %parameter%
echo Make FIleBehaveLikeUnchangedForGit Done.
GOTO END
:NOGIT
echo no git here.
echo %2%
:END

在我的预构建中,我将调用bat文件,例如:

call "$(ProjectDir)\..\..\MakeFileBehaveLikeUnchangedForGit.bat" "$(ProjectDir)Web.config.developer" "$(SolutionDir)"

我在SO上找到了一个蝙蝠文件,它将正确的配置文件复制到web.config / app.config。我还在预构建中将此蝙蝠文件称为。该bat文件的代码为:

@echo off
echo Comparing two files: %1 with %2
if not exist %1 goto File1NotFound
if not exist %2 goto File2NotFound
fc %1 %2 
if %ERRORLEVEL%==0 GOTO NoCopy
echo Files are not the same.  Copying %1 over %2
copy %1 %2 /y & goto END
:NoCopy
echo Files are the same.  Did nothing
goto END
:File1NotFound
echo %1 not found.
goto END
:File2NotFound
copy %1 %2 /y
goto END
:END
echo Done.

在我的预构建中,我将调用bat文件,例如:

call "$(ProjectDir)\..\..\copyifnewer.bat" "$(ProjectDir)web.config.$(ConfigurationName)" "$(ProjectDir)web.config
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.