Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A versioning workflow for multiple similar (but not identical) deployments

I'm currently employed at a small non-tech organisation and have been given the role of coding the organisations' website. While I have enjoyed the task and have learnt much with web dev I've encountered a few issues that I'm hoping someone will be able to help with me or at least point me in the right direction on.

A little background:

The site I work on has subdomains that each have their own separate WordPress installation on - as this has been the easiest "backend" admin panel for the type of user who will be responsible for updating content (etc).

Within the organisation I work under the Marketing Manager (MM) and I code according to his style guide and wire frames.

While we have been working with only one subdomain since the beginning of the year the project has been relatively simple and straightforward. However, lately the workflow is becoming a little more complicated as our original subdomain has been copied over to the other subdomains. Each of the new subdomains receives minor edits to their stylesheets (eg. different pictures for background, slightly different colours here and there, etc).

The issue:

At the moment managing all the different subdomains has been "bearable", but the straw that's braking the camel's back at the moment has been the slight reversions the MM has required now that the CEO has seen the final product. The problem I'm having with reversions in stylesheets is that the CEO will one week state that he likes change "X" and then as the MM and I continue to modify the site (to now "Z"), will another week state that he wants us to change "X" to "W" but keeping most of the changes made in "Y".

What I'm looking for is something that allows for:

  • tracking file changes
  • reverting changes made (or reverting back to 'a' from 'e' but including changes 'b' & 'c')
  • easily upload necessary files to their respective WP-theme installation

Does anything out there come close to addressing these issues? If so, what?

Thanks for any help!

PS - I'm learning Git at the moment and it seems to do the "tracking file changes" quite nicely. Haven't learnt about the reverting changes bit yet, though. Maybe for my final point I'm thinking of creating a shell script to automatically upload the files to their folders. Does Git do this too though?


Addendum (alexbbrown)

I had a similar problem: I ran a custom version of mediawiki where I installed various extensions in the versioned core (with svn). Each of the extensions required an section in the confit file, but the confit file also needed local configuration for each of several deployments. I could have implemented it using includes, but they would not be versioned; and rebasing branches each time is a chore. +50 experience points for a good answer in git.

like image 973
rs77 Avatar asked Aug 05 '12 06:08

rs77


2 Answers

Git will let you do what you need.

I'd use a single repository containing each subdomain as a branch, as in my experience this will allow you to move changes between subdomains in the easiest manner.

I'm going to assume a structure where you have a core branch, and several subdomainX branches each with their own local changes to maintain. I'll also assume you have a develop branch where you do core changes.

There are several key actions you'll need to be able to do:

You've made a change in develop that should go out to all subdomains

Pull the changes from develop into core

git checkout core
git merge develop

Apply the changes to the subdomain branches. For each subdomain run

git checkout subdomainX
git rebase core

or if you prefer merges over rebases (I find this case gets overly messy - but others may disagree)

git checkout subdomainX
git merge core

If you have a lot of subdomain branches then I'd script this. This will rebase all the local branches containing "subdomain" in their name onto core.

for i in $( git branch | cut -b 3- | grep subdomain ) ; do
   git checkout $i
   git rebase core
end

You've made a change in a subdomain that you want to pull into all other subdomains

First you'll need the SHA of the change you want to apply (and check it in if you haven't already).

Next you'll pull just that change into the develop branch, and then into core

git checkout develop
git cherry-pick THE_SHA_OF_YOUR_CHANGE
git checkout core
git merge develop

Then you just run the script above to push the change out to all of the subdomain branches.

You've git some changes that should be undone everywhere

git checkout develop
git revert THE_BAD_SHA
git checkout core
git merge develop

Then run the script.

You want to compare two subdomains.

If the two branches are called subdomainA and subdomainB you can do

git diff subdomainA subdomainB

You want to see what changes are in subdomainA but not core - i.e. the local changes.

The changes to the files can be obtained by:

git diff subdomainA core

The actual list of change-sets by

git log core..subdomainA

Handling distribution

There are two ways you could handle this:

  • Make a small script to copy up the files for each branch (I'd use rsync to avoid copying existing files etc.). The advantage of this is that it is fast and doesn't require git on the server you are deploying to.
  • Make each subdomains files be a copy of the git repository. Your script would then ssh to each box and pull/merge the files. An advantage of this is that you can make changes on the live servers and pull them back into your repository easily. Disadvantages include that you'll need to set up a bare repository as the origin for all the repos, and it will take up more space. (However IMO the advantages in this case outweigh the disadvantages and it is this approach that I would use).
like image 109
Michael Anderson Avatar answered Oct 15 '22 17:10

Michael Anderson


The answer by Michael is good, but there is another point of view I think should be mentioned: Branch by Abstraction (BBA) instead of the traditional “Branch by Source Control”. I think you should reorganize your source code so that shared code should be made as explicitly shared code instead of sharing by magic merges/rebases.

Maybe it worth to introduce some kind of build scripts which will rearrange code and run some tests to check correctness.

like image 20
kan Avatar answered Oct 15 '22 19:10

kan