在git中的web.config和app.config机器特定设置

33
我们有多个不同办公室的开发团队,在我们项目的web.config和app.config文件中需要不同的配置设置值。
我们希望将这些配置文件与合理的默认值一起检入,这样通过检出主干/主分支,您就可以获得一个可工作的东西,而无需查找配置文件。
历史上,我们使用过Subversion,特别是TortoiseSVN,这提供了一种管理本地更改的简单方法:我们只需将这些文件添加到TortoiseSVN的自动忽略提交更改列表中。这可以防止意外检入这些文件,因为您需要明确选择它们才能包含在检入中(并且您可以确保您正在检入重要更改,而不是本地配置噪音)。这种方法的主要缺点是配置文件始终看起来是“已更改的”,因此无法一眼知道是否有任何本地更改。
我们正在考虑切换到Git,并试图找出最佳方法。
首先,其他StackOverflow答案中已经有的内容:

选项1:将实际的配置文件放入xxx.sample文件和.gitignore中:这是推荐的做法,例如在此答案中提到。我看到的主要问题是,配置文件的更改很容易被忘记,在两个不同的点上:提交者很容易错过需要添加到.sample文件中的更改,消费者(特别是持续集成服务器)很容易错过他们需要从.sample文件中合并到本地配置文件中的更改。所以基本上,这似乎不是一个非常好的解决方案。

选项2:有一个已检入的xxx.defaults文件和一个.gitignored xxx.local配置文件,覆盖其定义的任何设置:例如,在这里提供了这种方法。问题在于,我们正在使用标准的.Net配置提供程序-当微软已经完成所有工作时,我真的不希望我们实现一个全新的设置加载框架。是否有人知道如何让app.config和web.config文件引用可选的本地覆盖文件?

选项 3: 让开发人员保留本地分支,然后始终将樱桃挑选或变基分支检入主干,以始终绕过/避免他们本地分支中不需要的提交: 这是一种可能的工作流程这里, 虽然我欣赏它在跟踪更改方面的整洁性(每个内容都被检入),但在每次检入时,它会引入大量的必需开销; 这真的很痛苦!

选项 4: 将配置文件检入,但将它们标记为--assume-unchanged: 这是一种可能的选项这里; 就我所知,这与 TortoiseSVN 中的ignore-on-commit更改列表非常相似,除了您在提交过程中无法看到这些“隐藏”的更改文件; 例如,TortoiseGit 显示具有“已更改”图标叠加的文件,但在提交对话框中,该文件根本没有显示出来。这似乎有点可怕,很容易忘记检查更改。

在这些可选项中,这是我找到的所有选项,我真的希望有一种方法可以选择性地将本地配置文件“包含”到已检入的app.config/web.config文件中,并使用选项2; 是否有人知道如何做到这一点,或者我遗漏了其他选项?(我微弱地考虑过一种自定义的Xml合并预编译步骤...)

我之前应该提到,我们仍在使用VS2008,因此无法使用配置变换。


更新:(已删除,是错误的)

更新2:我删除了之前的更新和答案,因为它很愚蠢/不起作用。 我没有意识到在进行“ours”合并后,在另一个方向上的下一次合并会将这些文件的“原始”版本带回(覆盖本地分支更改)。 如果您感兴趣,请查看编辑历史记录。 这个问题仍然是开放的。


你最终采取了什么方法?谢谢。 - Hewins
1
我们最终建立了一个内部工具,但我无法分享,因为需要跳过太多的步骤。它简单地支持“模板”文件中的占位符,并将其转换为“最终”文件。占位符到值的映射存储在一对简单的Xml文档中,其中一个是“默认”文档,已经检入,另一个是“本地”文档,未检入(.gitignored)。模板文件已经检入,但所有输出文件都被.gitignored。它可以运行在“覆盖差异”模式或“警告差异”模式下,在后者中,您希望使用最终(例如web.config)文件来更新相应的模板。 - Tao
5个回答

12
我建议您查看ConfigGen。我们在所有项目中都使用它,对于所有开发人员和环境都非常有用。它基本上运行于电子表格之上,指定机器名称和输出配置文件,然后将模板App.Config或Web.Config进行标记化,将电子表格中的值替换其中。在项目中添加一个简单的预构建步骤来运行Configgen,在构建开始之前就为您的机器获得了量身定制的配置文件。它还支持默认设置。
请查看该网站并自行决定,但我绝对可以担保它。
编辑:值得注意的是,您可以忽略Web.config和App.config文件(就.git而言)。但是,您需要将模板和电子表格添加到存储库中。此外,我可以保证,即将推出的更新可能会包含电子表格的XML替代品,具有自己的编辑器,使其非常适合DVCS。
Edit2:还要查看Daniel在这里的帖子:https://dev59.com/QGsz5IYBdhLWcg3wJUnJ#8082937。他提供了模板和电子表格的非常清晰的示例,以及如何在解决方案中使其起作用。

谢谢,这看起来是最简单/最明智的解决方案,我会去尝试一下。 - Tao
只是为了明确,我没有给你的答案点踩 ;) (特别是因为我在这个页面上有我的答案) - VonC
1
ConfigGen现在支持csv设置文件以及全局默认设置文件,允许您将全局设置存储在一个文件中,并将其与每个应用程序的更具体的设置文件合并。 - Daniel Dyson

7

你考虑过内容筛选驱动程序吗?

content filter dfriver

这意味着在每次git checkout时,粘贴脚本将根据以下内容生成实际配置文件:
  • 一个配置模板文件(带有配置值占位符,如@@A_PARAM_VALUE@@
  • 其中一个配置值文件(每个开发人员都可以保留版本控制自己的配置文件值)
这避免了任何合并问题和gitignore设置:每个“配置值文件”都是不同的并保持分离。
这也与其他配置生成解决方案兼容,例如ConfigGenpms1969答案中提到。

嗯,这看起来很有趣 - 需要去玩一下。 - Tao
1
好的,除非我在这里误解了什么,否则为了使这种流程正常工作,我们需要建立一个双向内容转换;从已检入到本地(替换占位符,或从某个单一占位符+模板+值文件构建文件内容),以及从本地到已检入(根据内容的某个可识别部分,用原始占位符替换原位文件/内容)。好处是它会在检出时自动执行(只要你使用的是git而不是像libgit2这样的东西?),但这看起来比自定义构建步骤复杂得多... - Tao
1
@Tao 是的,如果您需要存储对生成文件所做的本地修改,则会使用“clean”脚本。而且libgit2确实支持smudge(至少有一点点)。自从...4天前:http://article.gmane.org/gmane.comp.version-control.git/197996 - VonC

1

我建议您查看DanManaging complex Web.Config files between deployment environments答案,以寻找潜在的解决方案。我使用Mercurial,并使用相同的过程来检查通用的web.config文件,并使用Web转换将configSource的位置更改为指向我的部署特定内容。

使用此路线的优点是它完全内置于框架中,不需要额外的代码,并且与Web部署一起工作。

已检入的web.config:

<?xml version="1.0"?>
<configuration>
  <!-- snip -->
  <connectionStrings configSource="config/connectionStrings.config" />
</configuration>

在 web.debug.config 中进行了检查:

<?xml version="1.0"?>
<configuration>
  <connectionStrings
      configSource="config/dev.connectionStrings.config"
      xdt:Transform="Replace(configSource)" />
</configuration>

我有一个带有默认值的config/connectionStrings.config,但开发服务器上的config/dev.connectionStrings.config没有被检入,也不会在新部署时被替换。


3
只有在本地发布或作为调试到开发服务器时才有效,而在 Visual Studio 内运行时无效。 - CodeMonkey1313
你仍然可以采用相同的逻辑,只是反过来。在web.config中指定自定义.config文件,然后在发布时使用转换文件,然后只需在本地配置文件上执行.gitignore即可。通过使用configSource,.Net将自动合并不同的文件,而无需额外的代码。 - Joshua
嗯,我们被困在VS2008上,不使用Web部署(并且有其他非ASP应用程序组件),但是这个“configSource”东西值得思考,谢谢! - Tao

0
我们在公司遇到了类似的困境。最终,我们创建了单独的配置分支来补充主分支。例如:develop-config,master-config等。然后,我们有一个小脚本,根据部署环境将这些分支与正确的源分支进行合并。因此,例如,在开发机器上,我们将使用develop将develop-config进行合并。如果您正在本地计算机上工作,您将获得默认配置(所有开发人员都同意的), 这些配置已经被检入主分支(如本地数据库名称、密码等)。当然,缺点是您必须始终使这些*-config分支保持最新状态或在部署时将它们升级到最新状态。
自从实施这个工作流程以来,我遇到了一些部署工具,例如whiskey_disk ,它采用了类似的方法。实际上,我更喜欢他们的解决方案,因为它更安全和灵活。尽管可能不适合你们,因为它更适合LAMP/RoR开发堆栈。
除此之外,还有一些商业解决方案可供您参考,如Beanstalk

0
自2012年以来,一些事情已经发生了变化,现在我建议您的构建/部署工具(VS Team Services、TeamCity、Octopus Deploy)管理特定环境配置。
如果您在Azure上工作,您可以将应用程序设置和连接字符串定义为应用程序定义的一部分。

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