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

时间:2008-08-08 14:44:26

标签: svn git version-control cvs

假设您有一个典型的网络应用程序和文件配置。无论如何。每个开发该项目的开发人员都有一个版本用于他们的开发盒,将有一个dev,prod和stage版本。你如何在源代码管理中处理这个问题?根本不检查这个文件,用不同的名字检查或完全做些什么?

19 个答案:

答案 0 :(得分:63)

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

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

答案 1 :(得分:20)

不要对该文件进行版本控制。版本模板或其他东西。

答案 2 :(得分:20)

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

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

答案 3 :(得分:9)

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

答案 4 :(得分:6)

目前我有“模板”配置文件,其中添加了扩展名,例如:

web.config.rename

但是,如果关键更改发生了变化,我可以看到此方法存在问题。

答案 5 :(得分:5)

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

有一个 LOCAL,DEV,QA,PRODUCTION 部分,每个部分都包含配置文件中与该环境相关的配置键。

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

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

希望这有帮助。

答案 6 :(得分:4)

模板方法

+1。

但是因为这个问题有标签Git,分布式替代品 让我们想到,在私人测试中保留自定义 分支:

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

在此方案中,主线包含通用的“模板”配置 需要最少量调整的文件才能生效。

现在,开发人员/测试人员可以将配置文件调整到他们的心脏 内容,并且只在一个私有的本地提交这些更改 测试分支(例如B'= B +定制)。每次主线 进步,他们毫不费力地将其合并到测试中,从而产生 合并提交,例如D'(= D + B的自定义的合并版本)。

当“模板”配置文件更新时,此方案真的很棒: 双方的变化得到合并,极有可能 如果它们不兼容会导致冲突(或测试失败)!

答案 7 :(得分:4)

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

例如

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

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

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

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

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

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

答案 8 :(得分:4)

我之前使用过该模板,即web.dev.config,web.prod.config等,但现在更喜欢“覆盖文件”技术。 web.config文件包含大多数设置,但外部文件包含特定于环境的值,例如db connections。关于Paul Wilson's blog的好解释。

我认为这会减少配置文件之间的重复量,这会在添加新值/属性时造成痛苦。

答案 9 :(得分:3)

@Grant是对的。

我在一个拥有近100名其他开发人员的团队中,我们的配置文件未检入源代码管理。我们在存储库中有文件的版本,每次检出都会提取,但它们不会更改。

这对我们来说非常好。

答案 10 :(得分:2)

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

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

答案 11 :(得分:2)

app / web.config的签入普通版本应该足够通用,可以在所有开发人员的计算机上运行,​​并且可以随时更新任何新的设置更改等。如果您需要特定的一组开发/测试/生产设置的设置,使用这些设置检查单独的文件,如GateKiller所述,具有某种命名约定,但我通常使用“web.prod.config”,而不是更改文件扩展名。 / p>

答案 12 :(得分:2)

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

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

答案 13 :(得分:2)

很长一段时间,我完成了bcwood所做的一切。我在源代码管理下保留了web.dev.config,web.test.config,web.prod.config等的副本,然后我的构建/部署系统在部署到各种环境时自动重命名它们。你在文件之间获得了一定的冗余(尤其是那里的所有asp.net内容),但通常效果非常好。您还必须确保团队中的每个人都记得在他们进行更改时更新所有文件。

顺便说一句,我喜欢将“.config”作为扩展名保留在最后,这样文件关联就不会被破坏。

对于配置文件的本地开发人员版本,我总是尽力鼓励人们尽可能使用相同的本地设置,这样就不需要拥有自己的版本。它并不总是适用于每个人,在这种情况下,人们通常只是根据需要在本地替换它并从那里开始。这不是太痛苦或任何事情。

答案 14 :(得分:1)

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

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

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

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

当有人签出项目时,他会复制他想要在未跟踪的config文件中使用的配置文件,并且他可以按照自己的意愿自由编辑,但也有责任在他提交之前复制这些更改。其他环境文件根据需要。

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

这个流程起初可能有点复杂,但它有很大的优点: 1.您永远不必担心在没有备份的情况下在服务器上删除或修改配置文件 2.如果开发人员在他的机器上有一些自定义配置并且他的机器因任何原因停止工作,则相同 3.在进行任何部署之前,您可以区分developmentstaging的配置文件,看看是否有任何遗漏或损坏。

答案 15 :(得分:1)

我们在这里有两个问题。

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

    如果开发人员在转发环境中使用相同的文件,那么检查不需要的内容以更改主配置文件是非常容易的。

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

  • 然后我们遇到的问题是开发人员必须保持配置文件的副本是最新的,因为其他开发人员添加了新的配置设置。但是,某些设置(如数据库连接字符串)对于每个开发人员都是不同的。

  • 问题/答案没有涉及第3个问题。 如何在安装新版软件时合并客户对配置文件所做的更改?

  

我还没有看到一个好的解决方案   然而,这在所有情况下都很有效   我见过一些部分解决方案   (可以组合在一起   减少的组合   问题很多。

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

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

    同样适用于依赖注入设置。

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

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

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

  • 处理开发配置文件以获取送货配置文件。

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

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

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

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

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

    然后,在发送配置文件之前,可以将以“_userName”结尾的所有值条带化。

  

但是到底你是什么?   “配置文件的所有者”   负责任地管理   配置文件如上或   除此以外。他/她也应该做一个   客户面板上的差异   每个配置文件   装运。

如果没有这个问题,你无法消除对照顾人的需求。

答案 16 :(得分:1)

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

答案 17 :(得分: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上发现了一个bat文件,它将正确的配置文件复制到web.config / app.config。我也在prebuild中调用这个bat文件。此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

答案 18 :(得分:0)

我们只是保持生产配置文件的签入。开发人员有责任在将文件从源安全中拉出来进行暂存或开发时更改文件。这已经烧毁了我们,所以我不建议。