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
For a long time, I have done exactly what bcwood has done. I keep copies of web.dev.config, web.test.config, web.prod.config, etc. under source control, and then my build/deploy system renames them automatically as it deploys to various environments. You get a certain amount of redundancy between the files (especially with all of the asp.net stuff in there), but generally it works really well. You also have to make sure that everyone on the team remembers to update all the files when they make a change.
By the way, I like to keep ".config" at the end as the extension so that file associations do not get broken.
As far as local developer versions of the config file, I always try my best to encourage people to use the same local settings as much as possible so that there is no need to have your own version. It doesn't always work for everyone, in which case people usually just replace it locally as needed and go from there. It's not too painful or anything.
I don't think there's a single solution that works for all cases as it may depend on the sensitivity of data in the config files, or the programming language you're using, and so many other factors. But I think it's important to keep the config files for all environments under source control, so you can always know when it was changed and by whom, and more importantly, be able to recover it if things go wrong. And they will.
So here's how I do it. This is for nodejs projects usually but I think it works for other frameworks and languages as well.
What I do is create a configs
directory at the root of the project, and under that directory keep multiple files for all environments (and some times separate files for each developer's environment as well) which are all tracked in source control. And there is the actual file that the code uses named config
at the root of the project. This is the only file that is not tracked. So it looks like this
root
|
|- config (not tracked)
|
|- configs/ (all tracked)
|- development
|- staging
|- live
|- James
When someone checks out the project he copies the config file he wants to use in the untracked config
file and he is free to edit it as he wishes but is also responsible to copy these changes before he commits to the other environment files as needed.
And on servers, the untracked file can simply be a copy (or reference) of the tracked file corresponding to that environment. In JS you can simply have 1 line to require that file.
This flow may be a little complicated at first but it has great advantages:
1. You never have to worry about a config file getting deleted or modified on the server without having a backup
2. The same if a developer has some custom config on his machine and his machine stops working for any reason
3. Before any deployment you can diff the config files for development
and staging
for example and see if there's anything missing or broken.
Configuration is code, and you should version it. We base our configuration files on usernames; in both UNIX/Mac and Windows you can access the user's login name, and as long as these are unique to the project, you are fine. You can even override this in the environment, but you should version control everything.
This also allows you to examine others' configurations, which can help diagnose build and platform issues.
I have always kept all versions of the config files in source control, in the same folder as the web.config file.
For example
web.config
web.qa.config
web.staging.config
web.production.config
I prefer this naming convention (as opposed to web.config.production or production.web.config) because
The default config file should be configured such that you can run the application locally on your own machine.
Most importantly, these files should be almost 100% identical in every aspect, even formatting. You shouldn't use tabs in one version and spaces in another for indenting. You should be able to run a diff tool against the files to see exactly what is different between them. I prefer to use WinMerge for diffing the files.
When your build process creates the binaries, there should be a task that overwrites the web.config with the config file appropriate for that environment. If the files are zipped up, then the non relevant files should be deleted from that build.
My team keeps separate versions of the config files for each environment (web.config.dev, web.config.test, web.config.prod). Our deployment scripts copy out the correct version, renaming it to web.config. This way, we have full version control on the config files for each environment, can easily perform a diff, etc.
I version control it, but never push it to the other servers. If the production server requires a change, I make that change directly to the config file.
It may not be pretty, but it works just fine.