I am developing software that is in live use in three installations – lets call them “London”, “Glasgow”, and “Manchester”. There is also the system I develop on (“Developer”) and a system used for final confidence testing before release (“Staging”). Because I have control of Developer and Staging, I can set them both up with exactly the same configuration as London.
How do I maintain Glasgow and Manchester systems under version control, in an easy and convenient way, using GIT?
The “obvious” way is to have four branches – “London”, “Manchester”, “Glasgow” and master. Develop in master, and apply those changes to each version in turn using the git rebase command. This will work fine for the first and second changes.
By the 23rd change it becomes a pain. When one has a string of 30 commits , 6 of which have had to have manual corrections to merges, one gets very fed up of sorting out the same merge errors for every release. Conclusion – process is hard, and I had not got it right yet.
Time for a rethink
I put the git repository one level up, in effect creating a number of directories within the directory being maintained by git. One of these was the normal source directory (I am using php). Then I added a directory for each of the three systems, and a directory for the tests. (I use test driven development, and I want the tests under version control as well as the source code).
Finally I added a “specs” directory and put the specs and notes in there. (Much of the specification goes into a wiki (Wikid Pad – see http://wikidpad.sourceforge.net/), which stores the pages in one sub-directory.
Now I simply added a simple batch file to each of London, Manchester and Glasgow’s sub-directories, to set the main sources directory to reflect that systems configuration, by copying files. The destination files are NOT checked into the repository so I added them to the .gitignore file for convenience. Note that I do control the macros (.bat files) that do the copying.
Using the setup
I have three three copies of the repository – “Development”, “Staging” and “Reference.” The Reference system is a bare repository (one without a working directory) and is included in the daily backup. Both normal repositories point to the bare one as the origin.
To do some development work I use the “Development” repo and check out the branch I need (almost always master). When the development is complete and all the tests run, I commit and push the changes to origin.
To release, I open up GIT on the “Staging” repository, and pull from origin. This pulls all the changes from the bare repository. Then I do a local merge which applies the changes to the staging directories. The “Staging” directory is shared from a Linux machine, and I do the git work on the share.
But note that the Linux machine also has a web server serving those files. This environment is as near to the production server (appart from the share!) as I can make it.
A final run of the tests will prove nothing got broken, and then I excercise the system from the staging directories as a final confidence test.
Releasing is simplicity itself. I use rsync and a small (1 line) script on each production server. The steps are these:.
- Run the “configure.bat” file from the London sub-directory (thus configuring the directories to London’s needs.
- SSH into the London server.
- Run the releaseLondon script, which will use RSYNC to pull the changes out to the production server.
- Repeat the above 3 steps for Manchester (the script is releaseManchester).
- Repeat for the three steps again for Glasgow. Script is releaseGlasgow.
An normal “update” release to all 3 sites takes just a few minutes – and there has not been an error in the release process in the last 12 months.
- Everything is under version control – specification docs, sources, configurations, and the scripts that build CSS files and create button images.
- No long rebasing sessions.
- Merging errors are rare (they only happen if I modify source on Staging, and forget to move it back to Development).
- Release errors are caught as you test on the Staging system, and simply do not get into production.
- Staging, Development and Reference repositories are on different disks, so a loss of a spindle is not a serious problem.
- There is no opportunity to tidy up your release history. Your errors are all recorded for you to see later.