Goals

In almost any project it is necessary to have a local configuration that is different to the production configuration used on a server. That might include database access credentials, absolute paths, and other details. It’s easy to do such settings but it might be not convenient to work with such configuration files when using Git. Of course you could add them into .gitignore but that would not be the best approach since they could be adjusted during the development process (new variables, etc.) and those adjustments should be tracked by Git as well.

This article shows how to separate common code from a local configuration specific details during each synchronization with a remote repository and make sure you do not break the code of your production environment by pushing settings by accident. There are a few solutions already available online but they are either for large groups of developers or have certain problems that make their usage not convenient.

The approach developed by our team is described below. It is implemented using a few commands from our Git Cheat Sheet provided in the next article. Keep reading to get the idea first!

3-​branch Workflow Master-​Cfg-​Fix (MCF)

In order to accomplish the mentioned goals we are going to use 3-​branch configuration Master-​Cfg-​Fix (MCF) — a master branch, a configuration branch, and a branch to implement the fix you are working on. You can change the names of the branches but their purpose should be as follows:

  1. Master — the main branch with production settings. Keep in mind that you should not work on this branch. It has to be the same as the related branch on your remote repository to minimize the chance of getting into trouble while syncing with your local copy.
  2. Cfg — the branch that contains local configuration settings. It is inherited from the Master branch and is supposed to be used for settings needed for your local development (configuration files, etc.). This branch is also not intended for any changes related to tasks you might be working on.
  3. Fix — the development branch that is inherited from Cfg. All work should be performed here and once ready the changes should be moved into the Master branch and into the remote repository excluding the configuration changes made in Cfg.

In order to sync data between the branches mentioned above and with your remote repository after completing a task on the Fix branch you should follow the next steps:

  1. Fetch changes from your remote repository into your local master branch since while you were working the remote master branch could be updated by somebody else.
  2. Transfer the changes to the Cfg and the Fix branches.
  3. Move the changes from the Fix branch to the Master branch excluding changes made in the Cfg branch.
  4. Send the updated Master branch to the remote repository.
  5. Send a copy of the Cfg branch.
  6. Just in case do 1 and 2 again to make sure no new changes are available since synchronization was started.

Items 1 and 2 are implemented with the ‘git mcf-​update’ command that properly syncs the local branches Master-​Cfg-​Fix with the remote repository. Items 36 are implemented using the ‘git mcf-​upload’ command that updates the remote repository with the local changes. Note that you can easily change the names of these command to make them shorter if you would like.

In the figure below you can see the process of synchronization between the remote repository and the local storage before (left) and after (right) using the ‘git mcf-​update’ command.

Working with Local & Production Configurations Using Git. 3-Branch Workflow

Note that in order to simplify the figure we do not show that the remote repository also contains a temporary Cfg branch with the last commit from the local Cfg branch.

To summarize we would like to emphasize that working with a remote repository and local settings can be quite simple and error-​proof. You would need to use only a couple of commands suggested in this article. On the background these commands perform plenty of operations to automate using Git taking into account a vast number of potential problems. In 99% cases everything works smoothly and without any conflicts.