In talking with SourceGear customers, and with current or recovering SourceSafe users, and — to be honest — in my own past history, a painful task occurs all-too-frequently. I’m talking about the manual “push to production” of a particular fix, feature, or set of files for a web site. Just that set of files, no more, no less. And sometimes it’s tricky.
We had a customer ask recently how Vault might help them:
- Find just the files associated with a particular update…
- Warn if any of the files involved included changes for later, as-yet-unapproved updates…
- Fail in that case, otherwise…
- Copy those files to production
or in a more-perfect world,
- Move the affected files as they existed at the time the fix was checked in
- Unless later overlapping fixes have been pushed, in which case the latest approved-to-be-pushed version should be used
Having fun yet? They’re not.
It’s a common setup — imported as-is from SourceSafe; a single folder hierarchy for development; production is not under version control; and dev is at least several features ahead of production.
While we did discuss means by which they could use Vault’s Client API to script this sort of thing, I’d like to demonstrate how they might get off that treadmill, save themselves a ton of manual labor, and bring production under control.
The Problem – Fear of Branches
That’s not quite fair. Lack of branches is a problem. Fear of branches is one of the causes. If you’re coming from an older version control tool that makes branching painful (e.g. VSS), you’ll naturally avoid them. Times have changed.
In short, branches let you maintain parallel versions of a set of files and folders. You can migrate changes from one branch to another, freeze branches in time, etc. (for more detail and branching theory, see Eric’s Source Control HOWTO: Branches)
Branches are your friend, and Vault makes them easy.
The World’s Lamest Web Site
Can’t do a walkthrough without a demo app. Or in this case, a one-page web site written in roughly 15 seconds.
Here’s the hypothetical production version, the one out there on it’s own, non-version-controlled:
There’s a development version, too. It’s got a couple of revisions that haven’t yet made it to production. Some additional text was added, as was a style sheet:
Notice that after each change was checked in, a VSS-style label was added to note the milestone. In our case, we’re only modifying a single file; but those labels could mark the aftermath of many checkins over time.
Our customers, in this case, would like to be able to grab the files involved in the ADDED_COPY label (for example), and move them to production. Unfortunately, we can’t just grab the latest version of index.html — that would also bring over the style sheet changes, which we don’t want to move yet. And blindly grabbing the older version would be a problem if the style changes were approved.
It’s a manual process, as it stands. Spreadsheets are involved. That’s never a good sign.
A Better Way
What we want to do is to quit pushing versions of files, labeled files, no-later-than necessary files.
Pushing files isn’t the goal. The goal is to push the right changes. So let’s just do that.
Vault (and other modern version control tools, but this post is long enough as it is) handles a couple of things very nicely, which can make this process much simpler.
- Efficient, cheap Branching and Merging
- Atomic “change set” commits — that is, groups of edits, additions, deletions, renames, etc. all stored as one big change
What if the development tree was on a branch, and production on another? Maybe even a little staging/QA environment thrown in? Couldn’t we check in a feature as one or more changesets, and move those changesets independently from dev to QA and/or production? Wouldn’t that save us from manually tracking which-file-supersedes-which?
Yep. And more.
Getting there’s not too bad, although the middle part is kind of painful. But painful in exactly the same way as the current process, and then it’s done.
Mothball the current development tree
As it stands, the whole site lives under
$/demosite. Let’s make that a container folder, holding our branches. And then let’s move the existing tree to
$/demosite/demosite-old-dev for safekeeping.
We’ll leave it there, untouched. It’s handy for reference, but not where we want to live day-to-day from now on. Feel free to mark it read-only.
And start the new trees
Now we’ll create a new
dev folder under
$/demosite, and add a
prod folder as well. Set your working folders as you like, and copy the old dev files into the new
dev working folder. Copy the existing production files into your
prod working folder. Add the various copied files and folders to Vault.
Then branch the
prod tree into
The part that hurts
We now have a setup where future development can run very smoothly and safely. But what about those previous changes? How do they move up?
Mostly manually. Except that we’ll move them to the Stage tree for testing and evaluation. Once we’re happy with a change in stage, we check it in as a nice changeset. That gets moved to production, whenever we want.
The good news – we can do these all up front, whether or not we’re ready to move to production.
So for starters, we’d look at that
ADDED_COPY label. Notice the file(s) involved (just one, in our simple case). Get those files, from that labeled version, into our stage directory. Notice the diff once we’ve done so:
(In a more-complex scenario you might still need to edit the files somewhat to reflect only the change at hand. Like I said, this part is manual labor’s last stand.)
And we check that change in:
Then do the same with the style-sheet change:
Note that it’s important to do these moves in chronological order — but this is the last time we’ll need to worry much about that.
We now have changesets that can be merged into production as we see fit. So we can use the Merge Branches Wizard to move just the text changes to production, with no worries about file version conflict. (Changesets track changes, not static file versions). The styles can wait until later.
And see our results waiting to be committed:
We can even do them out-of-order without no extra effort. Merging the style changeset instead gives us all style, no copy:
And the next time you make a change in dev? It’s just another changeset waiting to be moved along.
Want to make things even easier? Have the
prod trees use shadow folders, and your check-ins drop automatically to their final destinations. No more worrying about production being out-of-sync with version control; they’re one-and-the-same.
So the new work flow goes like this:
- Developer makes a change, tests it locally, checks all relevant adds/edits/renames/moves in as one or more changesets.
- We move those changesets into the stage environment.
- The updates are automatically shadowed into our QA/staging web server root
- We test on QA
- When we’re satisfied, we merge the changesets into production
- And they’re shadowed to the production web server automatically
No more spreadsheets, no more manual builds, no forgetting to move the image file referenced in the new front page.
Of course, each developer could have their own private “sandbox” branch, as well. Or more than one. You can use Folder Permissions to control who gets to push to production and QA. And we haven’t even touched on using Fortress to track the whole thing.