web.config and app.config machine-specific settings in git

女生的网名这么多〃 提交于 2021-02-05 12:55:30

问题


We have multiple teams of developers in different offices, and they need different values for a number of configuration setting in our projects' web.config and app.config files.

We like to keep these configuration files checked in with a sensible set of default values, so that by checking out the trunk/master branch you have something working without needing to dig around for configuration files.

Historically we've used Subversion, and specifically TortoiseSVN, and this provided an easy way to manage local changes: We simply added these files to TortoiseSVN's automatic ignore-on-commit changelist. This prevents accidental checkin of these files, as you then need to select them specifically to include them on a checkin (and you can make sure you're checking in significant changes, not local-config noise). The main disadvantage of this approach is that the config files always look "changed", so it's not possible to at-a-glance know whether you have any local changes.

We're looking to switch to Git, and I'm trying to figure out the best approach.

First off, what's already there in other StackOverflow answers:

Option 1: Check in xxx.sample files and .gitignore the actual config files: This is recommended, for example, in this answer. The main problem I see with this is that changes to the config file are easily forgotten, at two different points: The committer can easily miss changes that they need to add to the .sample file, and consumers (esp. continuous integration server) can easily miss changes that they need to incorporate from the .sample file into their local config file. So basically, that doesn't seem like a very good solution.

Option 2: Have a checked-in xxx.defaults file and a .gitignored xxx.local config file which overrides any settings it defines: This is offered up, fr example, here. The issue there is that we're working with standard .Net configuration providers - I really don't want us to implement a whole new settings-loading framework when Mirosoft's already done all the work. Does anyone know a way to get app.config and web.config files to refer to optional local override files?

Option 3: Have developers keep local branches, and then have them always check in cherry-picks or rebased branches into master, to always bypass/avoid the unwanted commits in their local branch: This is offered as a possible workflow here, and while I appreciate the cleanliness of it in terms of change-tracking (everything checked in), it introduces a significant amount of required overhead on every single checkin; it's a major pain!

Option 4: Have config files checked in, but have them marked with --assume-unchanged: This is offered as a possible option here; as far as I can tell it's very similar in spirit to the ignore-on-commit changelist in TortoiseSVN, except you have no visibility to these "hidden" changed files in a commit process; TortoiseGit, for example, does show the file with a "changed" icon overlay, but in the commit dialog the file does not show up at all. This seems a little frightening, again very easy to forget to check changes in.

Given these options, which are all the ones I've found, I'm really hoping for a way to optionally "include" a local config file into/over a checked-in app.config/web.config file and go with option 2; does anyone know of a way to do this, or other options that I'm missing? (I'm faintly tempted to consider a custom Xml-merging pre-build step...)

I should have mentioned earlier, we're still on VS2008, so Configuration Transforms are not available.


UPDATE: (deleted, was plain wrong)

UPDATE 2: I've deleted my previous update and answer, it was stupid / didn't work. I didn't realize that after an "ours" merge, the next merge in the other direction carries the "original" versions of those files back (overwrites the local branch changes); see edit history if you're interested. This question is as open as ever.


回答1:


I'd like to suggest you look at ConfigGen. We use it in all our projects, and it works wonders for all the developers and also for all our environments. It basically runs off a spreadsheet that states machine name and output configuration file, and then tokenises a template App.Config or Web.Config, substituting values from the spreadsheet into it. Add a simple pre-build step to your projects to run configgen, and before the build kicks off, you have a tailored configuration file for your machine. It also supports default settings.

Take a look at the site and make your own mind up, but I can definitely vouch for it.

EDIT: It's worth noting that you can then ignore all your Web.config and App.config files (in terms of .git). But you do need to add your templates and spreadsheets to the repo. Also, I am assured there is an update on the way that may well include an xml replacement for the spreadsheets, that has it's own editor, making it eminently more suitable for DVCS's.

Edit2: Also take a look at Daniel's post here: https://stackoverflow.com/a/8082937/186184. He gives a very clear example of the template and spreadsheet, and how to get it working in your solution.




回答2:


Did you consider a content filter driver?

content filter dfriver

That would mean, on each git checkout, the smudge script would generate the actual config file based on:

  • a config template file (with config value placeholder like @@A_PARAM_VALUE@@)
  • one of the config value file (each developer can keep versioned his/her own config file values)

That avoid any merge issue and gitignore settings: each "config value files" are different and remain separate.
This is also compatible with other config generation solution like ConfigGen mentioned in pms1969's answer.




回答3:


I would take a look at this answer for Managing complex Web.Config files between deployment environments by Dan for a potential solution. I use mercurial and use this same process to have a generic web.config file checked in and use the web transforms to change the location of configSource to point to my deployment specific stuff.

The advantage of using this route is it is completely built in to the framework, requires no extra code, and works with web deployment.

Checked in web.config:

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

Checked in web.debug.config:

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

I have a config/connectionStrings.config checked in with defaults, but the development servers config/dev.connectionStrings.config is not checked in and its not replaced on a new deployment.




回答4:


We ran into a similar dilemma at our company. We ended up creating separate configuration branches which supplement the main branch. Like for example - develop-config, master-config, etc. We then have a small script which will rebase those branches with the correct source branch based on the deployment environment. So for example on the development machine we would rebase develop-config with develop. If you are working on local machine, you would get the default configuration (agreed upon by all developers) which is checked into the main branch (like the local DB name, password, etc). Of course the downside is that you always have to keep those *-config branches up-to-date or get them upto speed at the time of deployment.

Since implementing this workflow, I've come across couple of deployment tools out there like whiskey_disk which take a somewhat similar approach. In fact I like their solution a lot more since its much more secure and flexible. Although probably not a good fit for you guys since its geared more towards a LAMP/RoR development stack.

Aside from that, there are also some commercial solutions out there that you might want to take a look at like Beanstalk




回答5:


A bit has changed since 2012 and these days and now I would suggest your build/deploy tool (VS Team Services, TeamCity, Octopus Deploy) managing environment specific configurations.

If you work in azure you can define app settings and connection strings as part of your app definition.



来源:https://stackoverflow.com/questions/10142213/web-config-and-app-config-machine-specific-settings-in-git

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!