Monthly (dev trick) Column for February

Greetings! This continues a series of bulletins, this month focuses on aspects of how we do software development rapidly.

Tip: integrate often and quickly, but hold off actually making the branch until you really gotta.

This is an excerpt from some internal engineering documents, so that you can see how we approach this topic internally.

Today's topic - development branches

Sometimes, you have work to checkin and nowhere to put it.

We found that we needed to put out a release that included Perl/Python, but didn't want to check our Ruby scripts into "//depot/main/src/..." until release 2.0 went out.

Truth be told, there was no guarantee that release 3.0 was the right release for the Ruby stuff, either. (So any suggestions to check in the Ruby scripts into a 3.0-specific area don't hold up.) We needed a place to check in the work, knowing that it was safe and backed up, but whence we could retrieve our work to include "when the time was right."


First step: Deciding to create a development branch

Usually, you develop things in your workspace to check into the main codeline. A codeline or branch or tree (or whatever you want to call it) should have one guiding principle, which might be one of the following:

  1. The "main" area that we check new features/files into, that all new release lines are made from;
  2. The area where "release 1.0" is being finished up;
  3. The area where "release 2.0" is being finished up.
For this case, "where to put files that are incompatible with current work in a codeline/branch/etc" isn't addressed. Let's add a new branch whose purpose is:
  1. The "development" area where we can check Ruby scripts until it's okay to move them into "main".
This gives us a play-pen to make changes, independently of the "main" area in which the Python work's getting done.

Don't bother with development branches for short-term stuff. It's not worth it, since your workspace is really the best place to stage work. (Some sites have //depot/sandbox/myusername/... for you to make impromptu branches for such things. It's pretty useful.)

Second step: Where to put a development branch?

It's best to anchor a development branch under "main" if you can:

  1. That way, the new work isn't tied to a specific release while under development. If it slips or gets finished early, you can include it in the most convenient release.
  2. Also, it gives you a consistent place to put 'em.

You'll see that we always use named branch specifications for this work. (It makes the integration work consistent and avoids typos.) An example is below:

Branch:	rubydev2002

Owner:	eddie

Description:
	Created by eddie.

Options:	unlocked direct

View:
	//depot/main/src/... //depot/devbranches/ruby2002/src/...
	-//depot/main/policy.html //depot/devbranches/ruby2002/policy.html
	-//depot/main/include/version.h //depot/devbranches/ruby2002/include/version.h

Note the green text. It establishes that a new tree, //depot/devbranches/ruby2002, will pull its initial revisions from //depot/main when we run:

   p4  integrate  -b  rubydev2002  //...@2002/01/30
   p4  submit

So we'll end up with a new tree to work in, populated with a copy of //depot/main from the end of January. (Jan 30, and since we didn't specify time-of-day, it'll be the first second of the day.)

Third step: Working in a development branch

It's just a place to check in files - have at it.

The one detail is that you want to respect the branch's "goal." If it's a Ruby development branch, don't check in Perl bug fixes there.

Fourth step: Bringing your work back into normal development

At some point - perhaps several points along the way - you'll want to pull your work back to the parent codeline/branch. The reverse-integration adds a "-r" to the commands, but otherwise is fairly easy:

   p4  integrate  -r  -b  rubydev2002  //...@2002/01/30
   p4  resolve

The "resolve" step is straight-forward, but requires a bit of attention. (Don't use "accept theirs" to get the virtual-copy behavior - for back-integrations, it's usually a poor choice.)

Then, after many regressions and fixing things in your workspace...

   p4  submit

Last step: Obsoleting the branch

Once you've reverse-integrated everything, you need to stop using the development branch. ("main" lasts forever. Development branches shouldn't, so that you can always start with a fresh and blessed copy of the code for new work in a new branch. It's easier to maintain.)

Some people make the development branch invisible using "p4 protect" ; others delete the files in the development branch. The first one, with 'p4 protect', is the preferred approach. (It's best to avoid the second approach - you might accidently integrate the delete operations.)

Comments

A development branch is helpful for many situations - branching the entire tree, a small subtree, or just the Makefiles or header files. In the partial-tree case, you might map the rest of the production "main" into your workspace, so that - to you - it looks like a normal source area but meets your specialized needs.


$Id: //guest/jeff_bowles/scripts/0228devbranch.html#2 $
© 2004 Perforce Corporation, Inc.