{"id":55,"date":"2011-05-04T21:46:29","date_gmt":"2011-05-04T20:46:29","guid":{"rendered":"http:\/\/www.ianhobson.com\/?p=55"},"modified":"2022-01-28T21:55:16","modified_gmt":"2022-01-28T21:55:16","slug":"how-to-use-git-for-configuration-control","status":"publish","type":"post","link":"https:\/\/ianhobson.com\/index.php\/2011\/05\/how-to-use-git-for-configuration-control\/","title":{"rendered":"How to use GIT for Configuration control"},"content":{"rendered":"<h2>The problem:<\/h2>\n<p>I am developing software that is in live use in three installations &#8211; lets call them &#8220;London&#8221;, &#8220;Glasgow&#8221;, and &#8220;Manchester&#8221;. There is also the system I develop on (&#8220;Developer&#8221;) and a system used for final confidence testing before release (&#8220;Staging&#8221;).&nbsp; Because I have control of Developer and Staging, I can set them both up with exactly the same configuration as London.<\/p>\n<p>How do I maintain Glasgow and Manchester systems under version control, in an easy and convenient way, using GIT?<\/p>\n<p>The &#8220;obvious&#8221; way is to have four branches &#8211; &#8220;London&#8221;, &#8220;Manchester&#8221;, &#8220;Glasgow&#8221; 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.<\/p>\n<p>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 &#8211; process is hard, and I had not got it right yet.<\/p>\n<h3>Time for a rethink<\/h3>\n<p>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).<\/p>\n<p>Finally I added a &#8220;specs&#8221; directory and put the specs and notes in there.&nbsp; (Much of the specification goes into a wiki (Wikid Pad &#8211; see http:\/\/wikidpad.sourceforge.net\/), which stores the pages in one sub-directory.<\/p>\n<p>Now I simply added a simple batch file to each of London, Manchester and Glasgow&#8217;s sub-directories, to set the main sources directory to reflect that systems configuration,&nbsp; 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.<\/p>\n<h3>Using the setup<\/h3>\n<p>I have three three copies of the repository &#8211; &#8220;Development&#8221;, &#8220;Staging&#8221; and &#8220;Reference.&#8221; 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.<\/p>\n<p>To do some development work I use the &#8220;Development&#8221; 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.<\/p>\n<p>To release, I open up GIT on the &#8220;Staging&#8221; 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 &#8220;Staging&#8221; directory is shared from a Linux machine, and I do the git work on the share.<\/p>\n<p>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.<\/p>\n<p>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.<\/p>\n<p>Releasing is simplicity itself. I use rsync and a small (1 line) script on each production server. The steps are these:.<\/p>\n<ul>\n<li>Run the &#8220;configure.bat&#8221; file from the London sub-directory (thus configuring the directories to London&#8217;s needs.<\/li>\n<li>SSH into the London server.<\/li>\n<li>Run the releaseLondon script, which will use RSYNC to pull the changes out to the production server.<\/li>\n<li>Repeat the above 3 steps for Manchester (the script is releaseManchester).<\/li>\n<li>Repeat for the three steps again for Glasgow. Script is releaseGlasgow.<\/li>\n<\/ul>\n<p>An normal &#8220;update&#8221; release to all 3 sites takes just a few minutes &#8211; and there has not been an error in the release process in the last 12 months.<\/p>\n<p>Advantages:<\/p>\n<ul>\n<li>Everything is under version control &#8211; specification docs, sources, configurations, and the scripts that build CSS files and create button images.<\/li>\n<li>No long rebasing sessions.<\/li>\n<li>Merging errors are rare (they only happen if I modify source on Staging, and forget to move it back to Development).<\/li>\n<li>Release errors are caught as you test on the Staging system, and simply do not get into production.<\/li>\n<li>Staging, Development and Reference repositories are on different disks, so a loss of a spindle is not a serious problem.<\/li>\n<\/ul>\n<p>Disadvantages:<\/p>\n<ul>\n<li>There is no opportunity to tidy up your release history. Your errors are all recorded for you to see later.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>The problem: I am developing software that is in live use in three installations &#8211; lets call them &#8220;London&#8221;, &#8220;Glasgow&#8221;, and &#8220;Manchester&#8221;. There is also the system I develop on (&#8220;Developer&#8221;) and a system used for final confidence testing before &hellip; <a href=\"https:\/\/ianhobson.com\/index.php\/2011\/05\/how-to-use-git-for-configuration-control\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-55","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/ianhobson.com\/index.php\/wp-json\/wp\/v2\/posts\/55","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ianhobson.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ianhobson.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ianhobson.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ianhobson.com\/index.php\/wp-json\/wp\/v2\/comments?post=55"}],"version-history":[{"count":5,"href":"https:\/\/ianhobson.com\/index.php\/wp-json\/wp\/v2\/posts\/55\/revisions"}],"predecessor-version":[{"id":64,"href":"https:\/\/ianhobson.com\/index.php\/wp-json\/wp\/v2\/posts\/55\/revisions\/64"}],"wp:attachment":[{"href":"https:\/\/ianhobson.com\/index.php\/wp-json\/wp\/v2\/media?parent=55"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ianhobson.com\/index.php\/wp-json\/wp\/v2\/categories?post=55"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ianhobson.com\/index.php\/wp-json\/wp\/v2\/tags?post=55"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}