nobe4
nobe4

Reputation: 2842

Git custom merge to handle configuration files

So I was searching for a way to handle the configurations file in a git projet. I read some articles about the subject but all of them where suggesting a second, local-only file. And that doesn't feel right to me.

So I messed around with some of the git commands to find a way to achieve things another way.

A way I found this could be possible may be like this :

Files

The config for the example is a simple key : value list inside a file.

The local state is the lastest pulled version of the template :

1 : 1
2 : 2
3 : 3

The remote state is the version on the repository :

1 : 1
a : 2
3 : 3
4 : 4

On this file I have one new field : 4 and a modified field a.

Finally the working state is the configuration file used by the application. It is a copy of the local file modified with the secret values for running the application. This version should not be pushed to the repository.

1 : secret1
2 : secret2
3 : secret3

Flow

Here is the workflow I thought about :

On pull/checkout :

The last merge should provide user a display for the new field to add, as long as not overriding the existing fields values.

An example of such operation may be :

1st merge :

-    2 : 2
+    a : 2
+    4 : 4

2nd merge :

1 : secret1
-    2 : secret2
+    a : 2
3 : secret3
+    4 : 4

And now, before being able to use the application again, we clearly see the lines to changes.

What do you think ?

Upvotes: 1

Views: 287

Answers (2)

Fr0sT
Fr0sT

Reputation: 3025

I'd recommend you to think thoroughly WHY you do need to store config file in the repo? If that's some default option set then it probably should be integrated into project (maybe compiled into binary; IDK what your project is). If that's a sample option set then you needn't using it in your working tree so just ignore it when pulling. Anyway the software shouldn't be unusable when config file is missing, it should have some default values therefore you won't need to merge your working config with the repo's version.

I used to keep my configs in the repo but later changed my mind and removed all these commits. Config is a changeable state referring to user preferences; code repo is for storing the history of the code. Mixing these two subjects seems bad practice to me.

upd

If you don't want to support upgrading config from older verison to a recent one there is just one way I can imagine:

  • Store config template in the repo
  • Add a tool to the repo that upgrades actual config from previous version to the recent one (it could be a small program or even better a script)
  • Set this tool to launch on post-pull event.

So every time a dev pulls from remote repo, the config tool would be updated too and then launched. Tool committed in a revision upgrades actual config file from exactly the previous version to a recent version that was introduced in this revision. Obviously plain text tool is more preferable here (for tracking changes) but binary will work too.

Upvotes: 0

bufh
bufh

Reputation: 3410

I think an application should be able to read many configuration files, and only a default configuration file should be stored in the repository; for example:

  1. read /path/to/the/app/default.conf
  2. read a system-wide /etc/application.conf
  3. read user configuration (ie: ~/.config/application.conf), if it is in the same directory than the application, use a .gitignore

Some projects (like ansible with Vault) store an encrypted version of the configuration file, that could be a solution too.

Would it work for your setup?

Another suggestion would be a separate branch where you cherry-pick the code or the configuration, depending your preferences.

Edit: precisions about cherry picking.

This was just a suggestion, it's like your toughs about merging, except you choose which commits you want to get from the "remote".

On your machine, working in the local branch:

  1. git fetch
  2. either git merge master or git cherry-pick the commits you want

Nothing ground-breaking, I'm not sure if you expect the operation to be automated or manual.

Upvotes: 1

Related Questions