Keep different content of a particular file in a G

2019-04-07 07:23发布

问题:

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?

回答1:

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.



回答2:

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.


回答3:

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.



回答4:

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.