Let\'s say you have a typical web app and with a file configuration.whatever. Every developer working on the project will have one version for their dev boxes, there will be
We just keep the production config file checked in. It's the developer's responsibility to change the file when they pull it out of source safe for staging or development. This has burnt us in the past so I wouldn't suggest it.
Don't version that file. Version a template or something.
I've used the template before, i.e. web.dev.config, web.prod.config, etc, but now prefer the 'override file' technique. The web.config file contains the majority of the settings, but an external file contains environment-specific values such as db connections. Good explanation on Paul Wilson's blog.
I think this reduces the amount to duplication between the config files which can cause pain when adding new values / attributes.
+1 on the template approach.
But since this question has tag Git, the distributed alternative springs to mind, in which customizations are kept on a private testing branch:
A---B---C---D--- <- mainline (public)
\ \
B'------D'--- <- testing (private)
In this scheme, the mainline contains a generic, "template" config file requiring the minimal amount of adjustments to become functional.
Now, developers/testers can tweak the config file to their heart's content, and only commit these changes locally on one a private testing branch (e.g. B' = B + customizations). Each time mainline advances, they effortlessly merge it into testing, which results in merge commits such as D' (= D + merged version of B's customizations).
This scheme really shines when the "template" config file is updated: the changes from both sides get merged, and are extremely likely to result into conflicts (or test failures) if they are incompatible!
The checked-in, plain-vanilla version of app/web.config should be generic enough to work on all developer machines, and be kept up to date with any new setting changes, etc. If you require a specific set of settings for dev/test/production settings, check in separate files with those settings, as GateKiller stated, with some sort of naming convention, though I usually go with "web.prod.config", as not to change the file extension.
We have two problems here.
Firstly we have to control the configuration file that is shipped with the software.
It is all two easy for a developer to check in an unwanted to change to the master config file, if they are using the same file in the devolvement environment.
On the other side, if you have a separate configuration file that is included by the installer, it is very easy to forget to add a new setting to it, or to let the comments in it get out of sync with the comments in the devolvement configuring file.
Then we have the problem that developers have to keep there copy of the configuration file up-to-date as other developers add new configuration settings. However some settings like database connection strings are different for each developer.
There is a 3rd problem the question/answers do not cover. How do you merge in the changes a customer have make to your configuration file when you install a new version of your software?
I have yet to see a good solutions that works well in all cases, however I have seen some partial solutions (that can be combined in different combinations as needed) that reduces the problem a lot.
Firstly reduce the number of configuration items you have in your main configuration file.
If you don’t have a need to let your customers change your mappings, use Fluent NHibernate (or otherwise) to move the configuration into code.
Likewise for depency injection setup.
Split up the configuration file when possible, e.g. use a separate file to configure what Log4Net logs.
Don’t repeat items between lots of configuration files, e.g. if you have 4 web applications that are all installed on the same machine, have a overall configuration file that the web.config file in each application points to.
(Use a relative path by default, so it is rare to have to change the web.config file)
Process the development configuration file to get the shipping configuration file.
The could be done by have default values in the Xml comments that are then set in the configuration file when a build is done. Or having sections that are deleted as part of the process of creating the installer.
Instead of just having one database connection strings, have one per developers.
E.g first look for “database_ianr” (where ianr is my username or machine name) in the configuration file at run time, if it is not found, then look for “database”
Have a 2nd level "e.g. -oracle or -sqlserver" make it quicker for developers to get to both database systems.
This can of course also be done for any other configuration value.
Then all values that end in “_userName” can be striped out before shipping the configuration file.
However in the end what is you is a “owner of configuration file” that takes the responsibly of managing the configuration file(s) as above or otherwise. He/She should also do a diff on the customer facings configuration file before each shipment.
You can’t remove the need for a caring person some this short of problem.