web.config and app.config machine
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.
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.
Did you consider a content filter driver?
That would mean, on each git checkout
, the smudge script would generate the actual config file based on:
@@A_PARAM_VALUE@@
) 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.
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.
上一篇: iPhone的webapp设计