Search code examples
jsongitversion-controlconfigurationconfiguration-management

SCM for configuration statement versioning


My request probably seems to be a bit strange, but let me try to explain what I want to do.

So, first of all, what I want to version in the SCM isn't really the source code of something. It's JSON-files which contains statements to configure a specific server software (the server software saves its configuration in a database) using the provided api (there's a separate deployment tool). The only way to configure this software is using the api. So, the JSON looks something like this:

[{
  "command": "command1",
  "options": {
    "option1": "value1"
  }
}, {
  "command": "command2",
  "options": {
    "option2": "value2"
  }
}]

and so on and so on. So, now the configuration of this software is developed in Scrum and the result of each sprint needs to be a set of configuration commands which changes the software accordingly. This means, that the release package has to contain only the commands which weren't there the last release, too. So, what I currently think about (doing in git) is the following:

When a new sprint starts, I createa new branch in the repository and clear out all configuration files (there're several ones). I develop the configuration changes in the above mentioned JSON syntax and anything is fine. At the end of the sprint, the things in the branch is the release package (which only contains the delta configuration options from the previous release and this release). Now I would need to manually merge the branch back to the master to get an overall set of configuration options (e.g. to deploy a new server or rebuilt a server when it crashed or whatever). This is a manual task, however, I don't know how it could be done in a better way.

So, what I really want to ask into the round is: Does anyone know a better solution to manage the configuration files? The goal is to have a delta of configuration options from the previous release, which could be used to update the configuration of an existing server, and a release package which contains all configuration statements (master). I would really love to see a better solution, however, I don't know any.

Thanks in advance for any help! If you've questions regarding what I ask for, feel free to comment :)

EDIT 1: Based on the answer of @Marina - MSFT I thought about this a bit more. In git, something like this would probably work:

Let's assume a master like this:

|
C Another commit with changes to config2.json
|
B Some other commit with changes to config1.json
|
A First commit
|

So, currently the master tree contains two files, config1.json and config2.json, both have a JSON content like mentioned above.

Now, the next sprint (as an example, called "Sprint 1") starts and someone will create a new branch (git checkout -b dev for example). This person will also need to delete all files using git rm * and commits these chanes as the first commit to the branch, resulting in this graph:

---A---B---C---
            \
             D

D is the commit, which deletes all files. Now, I commit changes, which has to be done in this sprint (the configuration files will always only contain these changes). At the end of the sprint, I probably have a graph like this one:

---A---B---C---
            \
             D---E---F---G---H

So, because I only want E, F, G and H in the master, I don't merge the branch but instead cherry-pick all changes except D to master. Because I always edit the same files (config1.json and config2.json), git will ask me to merge these files manually (which is totally fine, I don't expect, that any tool can support me in merging files in the way I need to do it). After merging the graph should look like:

---A---B---C---E'---F'---G'---H'  <--- master branch
            \
             D---E---F---G---H    <--- dev branch

Now, I could rename the dev branch to Sprint 1 (git branch -m sprint1) or something like that and would have the delta release there and a full release in master. This should work, right?


Solution

  • If you want to do version control for files, git is a very popular way. For your detail requirement in git as below (if there has misunderstanding for your requirement, please correct):

    Treat master branch as main branch, every time, after finish a sprint you can merge it to master branch, master branch is the last previous version, and the branch you are working on is the current, so you can use git merge to deal the conflict files with delta configuration.

    Show as the below graph, when you start a new sprint, create dev1 branch (git checkout -b dev1) and make and commit changes for config files. Then merge dev1 into master branch (git checkout master and git merge dev1), you can solve the conflict files to keep delta changes, use git add . and git commit to finish the merge. The next sprint is similar.

          ______C_____                          dev1
         /            \
    A---B--new commit--D---E--new commit--G--H  master
                           \             /
                             _____F_____        dev2
    

    Note: when you create a new bench new master, the config files can’t cleaned automatically, you need to delete the files or use git rm * to delete all files.

    New solution bases on your edit:

    A---B---C                     master
             \
              D---E---F---G---H   dev
    

    If you use cherry-pick, you need do 4 steps to make changes for E,F,G,H to master. Of cause it can work correctly, but there are also two ways to make it easier:

    1. Rebase commit E,F,G,H to master branch for one command:

    git rebase --onto master <commit id for D> dev

    1. Because commitH has already contained changes for E,F and G, so you can only need to rebase/cherry-pick commitH to master branch. This will keep the master branch only contains the final edition for each sprint.