Question

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.

Was it helpful?

Solution

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).

OTHER TIPS

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.

Good idea for implementing git! It is definitely an indispensable tool to have in the development process. As you mentioned, git will definitely solve your "tracking file changes" issue and can also solve the other problems, there's just more of a learning curve. There are a lot of great resources on git but if you want a better idea of what git is (and what it isn't) and how it works I would recommend reading Git from the bottom up.

Reverting changes can be done very easily with git. First, you'll probably need to view your history of commits to find the one you'd like to revert to. This can be done simply by using the git log command (make sure you're in a directory tracked by git). There's a lot more information on that here. Once you know the commit that you want to revert back to, all you need to do is utilize the hash associated with that specific commit and run git reset --hard 6e3e02050a where 6e3e02050a is your commit's unique hash. More info, including some cool things you can do with that, here. This will immediately revert all your tracked files to that specific commit (you can revert individual files as well).

Believe it or not, git can also help you push your code to your servers automatically when you want to. This is a little more advanced and takes advantage of a post-receive hook. This facilitates deployment from development to a production site. As I mentoined this is more advanced so I won't get into the specifics of that here but there's a great tutorial that includes exactly what you want over on wp.tutsplus.com (Step 4 specifically).

Now all of these things are pretty easy to for a single installation but it gets a little bit more complicated when you have many sites all attached to the same development process. Again, git has some options.

I'm guessing at this point you might know a little bit about branching, if not there are lots of resources out there. Branches allow you to shoot off into exploratory or even entirely separate projects from your main "master" branch. It sounds like this is exactly what you want with all of your different installations that are all based off of the same master code. Another benefit of branching is that you can keep your branches up to date with any changes to the master as well as merge them back in if you want to. Another option is cloning. This is different in the fact that you are actually copying and entire repository, not just branching off of what you currently have. More info on that here.

It might take a while to figure out the best way to set everything up but I can guarantee that once you have some sort of process in place you will be very happy with the options and peace of mind that git can give you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top