April 22, 2015

Living La Vida Helix: Real World Case of Using Local Branches for Experimentation

Media & Entertainment

The 2015.1 Helix Versioning Engine release brought one of my favorite Git features to P4D; the ability to quickly make disposable branches for experimenting. Today I’m going to walk you through a time where they recently saved my bacon so you can see if they may help with your work.

First, let me set the stage.

The techcomm team at Perforce has decided to change the markup language we use for authoring our docs. Any sort of project like this is about as much fun as moving house. Docbook has treated us well but writing doc in XML is even less fun than writing build files in XML, if you can believe that, and so we’ve decided to move to asciidoc.

Recently we’ve been experimenting with asciidoc renderers, including a popular renderer called Asciidoctor. If you haven’t used it, Asciidoctor is a Ruby-based reimplemenation of the asciidoc application that is maintained a bit more aggresively and renders out to a few extra formats. Our existing doc pipeline is built around Docbook, and with Asciidoctor we can easily convert to Docbook 5.0 meaning we can greatly improve our writers' lives with barely a change to our pipeline.

So what’s the difference between asciidoc and the fork asciidoctor? 3 characters and a whole lotta syntax changes. I figured the swap would be quick, but after my first rendering pass I saw I was in for a world of hurt. I needed to rework a ton of our section headers, but I still needed to be able to fix any bugs in the docs over what was looking to be a multi-day project.

In days gone by I might have moved this experiment off to a branch in the shared server and pounded on it, but there was a good chance this experiment wasn’t going to last and I didn’t want my random experiments lying around. Thankfully I have local branches now to handle all this work locally and privately, allowing me to publish only the winning solution. Let’s look at the process.

First a quick update:

○ → p4 fetch
1022074 - no revision(s) above those at that changelist number.
No changes to fetch.

I was already up-to-date so I’m ready to get to work.

Time to create a branch:

○ → p4 switch -c asciidoctor
asciidoctor

Excellent. A green field to play in. After quite a bit of tweaking I learned that what I thought might be a disaster was just the result of some differences to the table syntax. 30 minutes of clean up and I was back in business. However in cleaning up the content I had rejiggered the headers, and now I wasn’t sure if my TOC was the same. I needed a way to see a render of the original code in a hurry, so I popped back to my main stream that I had branched from.

○ → p4 switch main
○ → asciidoc adoc/p4dvcs.txt

A quick view of the rendered doc showed that I had indeed screwed it up. Time to flip back to my work.

○ → p4 switch asciidoctor

Perforce had automatically shelved my work in progress when I moved to main, and it dumped it back in place as I came back to my asciidoctor branch.

So what did I mangle? A quick diff2 will let me know:

○ → p4 diff2 -uS asciidoctor

I’ll spare you the output, but a spurious '=' had snuck in during my edits and thrown off my headers. A quick edit and I was right as rain. Now to get my changes into the shared production server!

○ → p4 switch main # putting myself in the branch that I have mapped to my 
shared server
○ → p4 merge --from asciidoctor # pulling in my changes
○ → p4 resolve -as              # resolving any differences; they should all 
be in my 
asciidoctor branch
○ → p4 submit -d "Adding asciidoctor support to DVCS manual" # submitting my 
merge commit
○ → p4 push # pushing my changes to the shared server

With minimal fuss I was able to experiment, find a solution, and get it back to my team. Technically everything I did here is possible when working in a centralized fashion, but for some reason I find it much more freeing to do it using our new distributed features. I think the major difference is I can commit frequently to checkpoint my ideas, but only have to publish the ones that work out. It cuts down on noise for my team, and we could all use a little less noise.

If you’d like to try this all out yourself you can grab a copy of 2015.1 and point it at our open source community server, the Perforce Workshop. Grab yourself a copy of the p4 source or maybe Piper and branch to your heart’s content.