Wednesday, July 14, 2010

A Git for my sanity

A few months ago, I converted all my SVN projects at work to Git. This was mostly due to the messiness that is SVN properties when doing merges. I was hoping Git was going to cut down on that, and it has somewhat, but I feel I'm missing something.

Here's a short description of one of our products. The state of play when we moved from SVN to Git was a bit shakey, as far as branches are concerned, so only after the next release will Git be working like I want it to, and how it should.

For now, I've got three "branches" to deal with.

The first branch is my "prod" branch. It's actually called "prod-20100612_email_paed_recalls", and it's a bugfix branch for what is currently live on the one site that I have to maintain it on (lucky me, it's a custom application, so I control releases to site, etc). In perfect Git work, this should actually be the "master", but for now it's not.

The next branch is the "master" branch. At the moment, it contains the next branch of work that will be delivered in the next release. I deliver that to an external environment called Staging, where the clients get to test before it all goes live. When it does go live, then I can do away with the prod branch, and use the master branch how it was meant to be used. One thing I'm looking forward to in this branch is code delivery via Capistrano.

And my final branch is the "dev" branch. It's actually called "dev-20100712-mo" and contains the next batch of features currently in development for after the current "master" branch goes live. Fortunately, this branch was cut from the master, so at least there's properly maintained history.

Now, here's the workflow for when I have to update any of these branches. If you've got any suggestions as to how to do them better, I'm welcoming any suggestions. I'll probably even post something to Stack Overflow, asking for help.

Oh yes, I should mention. Because I have to make regular updates in each of these branches, I've decided to have a clone of each one. I also have a remote called origin, where they all get pushed to, and backed up.

Workflow One: The Bugfix for Production.

So, I end up making a change to the "prod" branch because of some production branch (suffering alot of "this was here, now it's not" issues because forward migration in SVN was a PITA).

Once I've committed the change in prod, I go to my master directory, and do the following:

$ git checkout prod
$ git pull
$ git checkout master
$ git cherry-pick XXXXXXXX
$ git push

Because prod and master don't have the nice branch relationship that master and dev to, I have to cherry-pick my changes across. I'm okay with this. I haven't tried it yet, but I'm hoping to streamline this down to (from master):

$ git pull
$ git cherry-pick XXXXXXXX
$ git push

Next step, is making sure this production fix makes into the latest development release, so over I go to my dev directory. And I do:

$ git checkout master
$ git pull
$ git checkout dev
$ git merge master
$ git mergetool && git commit # usually
$ git push

The problem with this is I always end up with normal merge conflicts, for which I have to run the mergetool. SVN was able to deal with these with no prompting, so this is a step for which I feel I'm missing something.

Possibly a better way to deal with it is (from the dev branch):

$ git pull
$ git merge origin/master
$ git mergetool && git commit # if needed at all
$ git push

The only downside is the master in the dev directory gets out of date. Theoretically, it shouldn't be a problem, it should just be a matter of checking out the master branch and doing a pull. It hasn't really worked out that well, so far.

Workflow Two: The Bugfix for Staging.

This is pretty much the same as the first workflow, except I only have to deal with the master and dev directories, and there's no cherry picking involves.

Workflow Three: Development.

Well, this is essentially the last step of the last two workflows. I do some development, commit the work, push it to origin so it gets backed up (and one day, another developer may get to play with it), and then I want to pick up any changes that have happened in the master so they don't get lost ("they" being bugfixes to either production or staging).

I just hate seeing every second line in my dev branch gitk view reading "Merge branch 'master' into dev-20100712-mo" (or "Merge remote branch 'origin/master' into dev-20100712-mo", for the one occasion I've tried so far).

I'd rather update sooner and often, and I feel that's the right thing to be doing, but it just "looks" messy, and I'm not sure that leaving the merging of master back into dev to pick up bug fixes on the near completion of the dev feature branch is the right thing to do.

Any helpful hints for a seasoned Git user?

(Now just got to whittle that down to something consumable for Stack Overflow).

No comments:

Post a Comment