Git best practice for config files etc

GitGithubConfig

Git Problem Overview


I'm still new to all things git and was wondering what is best practice in regards to config files. My local development server needs different config values to my live one so how can I stop it pushing / pulling those files?

Git Solutions


Solution 1 - Git

Use symbolic links.

Take an example where you have a config file named "config.ini". In the working directory of your git repo, you would do the following:

  1. Create a version of the config file called "config-sample.ini". This is the file you'll do all your work on.

  2. Create a symbolic link between "config.ini" and "config-sample.ini".

     ln -s config-sample.ini config.ini
    

    This let's all your code point to "config.ini" even though you're really maintaining "config-sample.ini".

  3. Update your .gitignore to prevent the "config.ini" from being stored. That is, add a "config.ini" line:

     echo "config.ini" >> .gitignore
    
  4. (Optional, but highly recommended) Create a .gitattributes file with the line "config.ini export-ignore".

     echo "config.ini export-ignore" >> .gitattributes
    
  5. Do some coding and deploy....

  6. After deploying your code to production, copy the "config-sample.ini" file over to "config.ini". You'll need to make any adjustments necessary to setup for production. You'll only need to do this the first time you deploy and any time you change the structure of your config file.

A few benefits of this:

  • The structure of your config file is maintained in the repo.

  • Reasonable defaults can be maintained for any config options that are the same between dev and production.

  • Your "config-sample.ini" will update whenever you push a new version to production. This makes it a lot easier to spot any changes you need to make in your "config.ini" file.

  • You will never overwrite the production version of "config.ini". (The optional step 4 with the .gitattributes file adds an extra guarantee that you'll never export your "config.ini" file even if you accidentally add it to the repo.)

(This works great for me on Mac and Linux. I'm guessing there is a corresponding solution possible on Windows, but someone else will have to comment on that.)

Solution 2 - Git

Various options are available:

1. Commit a default config file, but allow a local config file

Add a file default.conf to your Git repository.

Your app first looks for app.conf but if that does not exist, it uses default.conf.

Users who want the non-default config can copy default.conf to app.conf and then edit it.

Users should not commit app.conf into the repository, because different users may want different settings in that file. (So you should put app.conf into your .gitignore.)

Your app always loads default.conf but if app.conf is present then it will copy settings from app.conf over the settings from default.conf.

This twist has a couple of advantages:

  • app.conf only needs to hold the differences from the defaults, making it smaller and easier to maintain.

  • When the app changes, new defaults added to default.conf will be available to the app, without the user having to copy them into app.conf.

> This solution is pretty similar to Alan W. Smith's answer above, with a small difference: If the app can start without the app.conf file being present, then it will run out of the box. However, it does add some complexity to the app's startup code. > > The suggestion was one of a few made by Linus Torvalds on a git or kernel mailing list, but I have not been able to find it today.

2. Use environment variables and/or command line arguments

You can use an environment variable to point your app at a specific config file. You might start your app like this:

CONFIG_FILE=test.conf ./start-app

or alternatively:

./start-app --config=test.conf

This means you can have multiple config files development.conf, staging.conf and production.conf. When you start the app you tell it which config file to use.

Developers who want to experiment with a different config can point at their own file, e.g. custom.conf.

You can also use environment variables or command line arguments to override specific settings:

./start-app --config=default.conf --db-url=... --debug-level=5

3. Different branches

You can keep your default config in your master branch.

Fork off different branches for each of your different environments.

Each branch can modify the default config file as needed.

When your master branch updates, merge from master into your specific branches.

Personally, I don't recommend this approach. I think it's harder to maintain.

Solution 3 - Git

Git will ignore files that you don't explicitly add, so checking different branches out just leaves them where they are in the directory structure as the other files change around them. If you add your config file to the .gitignore file in your repo's root (may have to create it, more info here) then you can still do all-files commands like

git add .

if you want to and not worry about it.

Solution 4 - Git

Best way is create a file called ".gitignore" and insert the files/folders you want to ignore.

This way you can make git add * everytime

Solution 5 - Git

I've always made the default config file with another name, e.g. rename_to_config.ini. The program tries to read config.ini and returns an error if it doesn't exist.

Pros:

  • I can keep the real config.ini in .gitignore and it won't be added with git add ..
  • You can confirm that the user has to consider the config file, in case it has mandatory fields like database info.

Cons:

  • Users cannot instantly run the program with the default configuration.
  • Probably not a very standard way to do things.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMartin HuntView Question on Stackoverflow
Solution 1 - GitAlan W. SmithView Answer on Stackoverflow
Solution 2 - GitjoeytwiddleView Answer on Stackoverflow
Solution 3 - GitMatt GibsonView Answer on Stackoverflow
Solution 4 - GitjribeiroView Answer on Stackoverflow
Solution 5 - GitAndriView Answer on Stackoverflow