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.