I have a config.php
which suppose to be different in content in different branches, e.g. testing
and master
.
I have asked in another question (Prevent merging a file from master with Git) that how to prevent this file from merging.
But I am wondering, is this the correct way to do so?
I believe this is quite a common use case to have different config files in different environments and you want the config to keep tracked, right?
The classic way to do this is to have a default config file called config.yml-dist (let's pretend that your original file is called config.yml) ; you add the original file in .gitignore, and version only the dist one.
After you deploy your app or re-clone the project, simply cp config.yml-dist config.yml
, and change the settings you want.
This method is used by many people I met in the PHP industry.
But, there's one I like much more and that I find cleaner: using environment variables.
Example:
username: <%= ENV['MONGOID_USERNAME'] %>
password: <%= ENV['MONGOID_PASSWORD'] %>
database: <%= ENV['MONGOID_DATABASE'] %>
This way, you'll have one single versioned configuration file and won't have to edit a single one.
For a config file, one solution is to not version it (that way, no merge issue!)
You would use a content filter driver:
You would version:
- one value file (for
master
environment)
- one value file (for
dev
environment)
- one template file (with placeholder variables like
@PORT_NUMBER@
)
- one '
smudge
' script able, based on the current branch, and based on the content of the checked out file (here the template file) to generate the actual config file (which remains 'private', ie not-versioned).
- one '
clean
' script able to detect any value changes in the private config file, and store those changed values back in the (versioned) value files.
You can have the master branch not contain that file, and only have it in the branches -- that'd be the easiest way.
Alternatively, and assuming the master configuration is reasonably stable, or else this'd be a big pain -- commit the config.php
changes in each branch and then always pull with rebasing when you get changes from master
so that the configuration changes are reapplied each time.
Why wouldn't you store all the environment-specific config files in the main repo? Then, either during build or deployment process, you would take whatever configuration file is relevant. There are lot of different ways of implementing it, depending onyour build/deployment tool, but any way you do it I think it is be better than having it in branches.
My opinion is that you definitely want the config files to be stored in version control and deployed using a deployment tool, so you wouldn't have old versions hanging around due to lack of updates or manual error.
Usually there exists a folder structure like
/configurations/test/properties/
/configurations/prod/properties/
and the deployment tool uses them per environment as requested. Any confidental information such as passwords can be either hashed or encypted: tehcnologies like ansible vault support this directly.