I Wonder What This Button Does
Issue № 220

I Wonder What This Button Does

The instantaneous reaction to screwing up a piece of a project is, generally, denial. That file wasn’t actually deleted, was it? Changing the configuration didn’t really break the application, did it?

Article Continues Below

It was. And it did.

Let’s skip right over anger, bargaining, and depression, shall we? You messed up, and your previously exciting weekend is now looking more and more like a frantic struggle to make everything work again before anyone notices.

Problem? What problem?#section2

Happily, there are solid technical solutions for avoiding this sort of mistake. A revision control system like Subversion provides the ability to wrap up all the files associated with a project and manage the changes made over time. In essence, Subversion can act like a time machine, zipping you back to that sublime moment just before you ruined your Saturday.

Even better, you aren’t the only one that Subversion helps. Your whole team can use Subversion in order to moderate the everyday disasters that occur when more than one person tries to work on a project at the same time. Bob and Alice both edited coolNewThing.html? No problem! If they edited distinct pieces, Subversion can automatically merge the changes. If their edits overlap, Subversion notifies them of the exact points of conflict (and, importantly, whose code they’re in conflict with) so that Bob and Alice can sit down together to resolve the issue instead of scratching their heads when their hard work simply disappears.

So how does this work?#section3

Surprisingly little of your workflow needs to change when moving to a revision controlled environment. The process boils down to four basic steps:

  1. Make sure you’re working with the most recent version of the project.
  2. Do some work.
  3. Test your work (and fix the bugs you introduced).
  4. Tell everyone else about your changes when you’re satisfied.

You were presumably doing all of these things already. Revision control just makes it easy.

Keeping up to date#section4

In a team environment, it’s dangerous to work with project files that have been sitting on your computer for a while. Other people are working just as hard as you are, and their changes are eventually going to overlap with something you’re about to start playing with. Inevitably, you’ll overwrite someone else’s work, or they’ll overwrite yours. The unbelievably widespread practice of e-mailing zip files around is marginally effective, but it’s an inefficient, cumbersome, and error-prone workaround.

Subversion solves this problem by creating a centralized storage location, called a repository, that acts as the team’s shared source for project data. By managing your project within a repository, you can keep track of all the important changes to all the files you’re interested in.

When I’m ready to start working, I first ask Subversion to make sure that all my files are up to date (as you might expect, Subversion calls this process an update). It compares my working copy with the latest revision of the project in the repository. If any of my files are out of date (or have been accidentally deleted), they’re automatically brought into line with the latest and greatest.

Once I’ve updated my working copy, I know that I’ve got all the important changes up till now, and I can start working without fear of accidentally overwriting someone else’s work.

Doing work#section5

Sorry, Subversion can’t help you here. Much like the homework-doing robots I always dreamed of as a child, the coding-for-you revision control system is still a couple of years off. That said, Subversion does facilitate experimentation and creative freedom, as you’ve always got a “safe” copy to revert to if your experiment fails miserably.

Testing your work#section6

Subversion can’t tell you whether your code works, but it can be a handy resource if you find that your code doesn’t work, or worse, breaks something that worked yesterday.

You’ve got a complete record of all the important changes to your files right there at your fingertips, so you can very easily “diff” your (broken) working copy against the (functional) previous version to see exactly what lines of code you changed. Seeing what’s changed is stunningly useful for diagnosing any issues you’ve inadvertently created, as you’ve narrowed the problem down to a very specific subset of the total project.

Distributing your work to your team#section7

When you’ve completed a chunk of work, you need to make sure it gets recorded as an important change in the repository and is thereby shared with your team. This process, known as a commit, merges the changes you’ve made to your working copy with the repository, ensuring both that everyone else on the team has access to them, and that the code is safely stored somewhere other than your disaster-prone desktop.

Importantly, Subversion doesn’t just capture the changes from revision to revision; it also captures context by allowing you to enter free-form notes along with your committed changes. Rather than just dumping a few new files into the repository and sending out an explanatory e-mail that will be forgotten as soon as it’s read, you can record the content of those changes directly in the repository. When Bob’s got questions or accidentally creates a conflict with Alice’s revision, he can just check her change log and see that she:

  • Added a snazzy sidebar to `coolNewThing.html` and modified style rules in `coolNewThing.css` to support it.
  • Changed the default link colour to periwinkle blue, per customer request.

This is critical information, and it’s kept right there with the files where it can do the most good. Embedded context is light-years better than a forgotten e-mail, and is reason enough to implement Subversion.

Next steps#section8

Obtaining Subversion is a trivial process. Just grab the distribution appropriate for your operating system and install it. This will load the client and server utilities onto your machine.

Setting up and maintaining a “real” networked Subversion server for a group is beyond the scope of this article; it’s really a task for your friendly sysadmin or IT department. That said, many web hosting services provide Subversion repositories as part of your hosting package, and there are a few excellent companies that specialize in hosting repositories.

For a quick taste, I’d highly suggest looking at O’Reilly’s excellent (and Free) Version Control with Subversion, which has a stellar Quick Start that walks through the process of creating a locally hosted repository, and interacting with it. This walkthrough covers about 80% of your interaction with Subversion, and is well worth the read (and purchase, for that matter).

Additional resources#section9

If you’re already comfortable with the command line, you’ll be pleasantly surprised at how simple it is to integrate Subversion into your everyday work. If not, there are a number of brilliant GUIs that make Subversion a breeze for those disinclined to pop open Terminal and type svn up every morning and svn commit every few hours:

  • RapidSVN is a cross-platform Subversion GUI that wraps up pretty much everything you’ll need into a fairly well laid-out interface.
  • Eschewing a traditional GUI, TortoiseSVN directly integrates with Windows Explorer, offering an intuitive, file-based mechanism for keeping your project up to date.
  • Many text editors and IDEs can directly interact with Subversion: Xcode, TextMate, BBEdit, Visual Studio, and Eclipse are the tip of the iceberg, check your favourite!

Finally, there’s a lot that Subversion can do for you that I haven’t mentioned yet. Branching, tagging, post-commit hooks, and other useful features are described in detail in the book I mentioned earlier: Version Control with Subversion. It’s a comprehensive look at what Subversion does, how it works, and best practices for it’s use in your projects.

About the Author

Mike West

Mike West abandoned suburban Texas’ wide open plains in 2005 in favour of the Black Forest in Southern Germany where he currently lives and works. He’s on the editorial team of Digital Web Magazine, and his musings about the web are periodically posted to his personal website, mikewest.org.

42 Reader Comments

  1. It’s sad, that so many web developers don’t use version control software. It’s even more sad, that a lot of universities don’t don’t include nothing about version control into their Computer Science programs.

    Even when you are working alone, you should place all you projects under version control. In addition to saving your ass when you screw things up, it gives you a nice overview of how the project has evolved over time and answer to questions what the hack were you doing last monday?

  2. Subversion is also handy for server config files, not just those of applications. I work alone, so collaboration functions are virtually irrelevant, but version control makes the process of configuring and tweaking Apache, MySQL, etc. not only faster but less stressful.

  3. …to get off my bum and implement Subversion. We run it at work, and it has been a lifesaver for your internal application development.

    Sadly, I don’t use it (yet) in my own web-design business. I spent a majority of the weekend trying to fix a problem with a site (in IE) that I sloppily introduced into functional code while working late on Friday. The problem was that I made a lot of changes and I had copies of incremental code changes in different places on the drive. (Horrow show, isn’t it?)

    So, time lost and lessons learned equals solutions implemented.

    Thanks for reminding me about something I already knew about. And thanks for the inspiration to get off my bum and implement Subversion! 🙂

  4. *Martin*: You’re right, “Trac”:http://trac.edgewall.org/ is indeed a great tool for groups using Subversion to develop an application. It wraps bug tracking, a development wiki, project planning, and release distribution up into a nice little package. And it’s open source, to boot. Doesn’t get much better than that.

    On various projects, I’ve also used “FogBugz”:http://www.fogcreek.com/FogBugz/ which is every bit as impressive. It’s really a wonderful program for development environments, and it’s interface runs circles around every other bug reporting/tracking suite I’ve seen.

    *Rene*: I agree completely. I’ve been surprised more times than I’d care to mention by people passing around dated zip files for development. Building and using a repository simply pays for itself over and over again in terms of averted misery… The contextually embedded commentary on the project’s changes over time are a stunningly effective hoard of information, even if the only person seeing them is you.

    *Cory*: Absolutely! Anything that’s critical to a project’s functionality can be wrapped up into your repositories. In fact, some people “go a little further(Keeping Your Life in Subversion)”:http://www.onlamp.com/pub/a/onlamp/2005/01/06/svn_homedir.html than just config files…

  5. Subversion is great, but for first time users, maintaining separate development tasks (Branches) and merging changes back into trunk can be quite a headache. It really does take some reading of the documentation to fully figure it out.

    Some tips that might be helpful to new users:

    # If you want to save time on the installation, use the included svnserve daemon instead of apache.
    # When replacing a file, avoid deleting the old one and dropping the new one in. It’ll break the reference between them. Instead, copy the contents of the new file into the old one.
    # When creating Branches, include the revision number that it was created from in the commit comments.

  6. *Damian*: Wonderful! Not the losing data part… The installing and using Subversion part. That’s exactly why I wrote the article! 🙂

    *Kev* and *Clayton*: Thanks for the links. I haven’t really found a GUI I like yet, but I’m a little odd and live on the command line anyway. So keep those suggestions coming, I’d love to see them.

    When the commenting dies down here, I’ll wrap all the GUI suggestions up and see if we can either add them to the resources section of the article or just add them in as a summary comment at the end.

    *Luke*: You’re right, branching and merging is a pretty advanced topic. I’d suggest doing your research before hopping into the deep end. Really, just doing basic development along the main trunk covers 95% of the scenarios you’ll ever find yourself in. For the other parts, curl up with O’Reilly and figure things out. 🙂

    I like your suggestions, as well, but I’d like some clarification for #2. What’s going on there that “*svn mv file1 file2*” wouldn’t handle?

  7. Mike: My experience with #2 is solely using Eclipse with the Subclipse Plugin. I had an external developer working on their own branch who deleted and then replaced 2 key css files. When the time came to update the branch from trunk, it took some time to figure out what they had done and resolve the issue.

  8. I understand the usage of SVN to control desktop software, but it would be helpful to see an example of how to use it for a *website*.

    Is the site itself the repository? Or is the site a checkout of the repository? Am I going to need to run a server on my local machine, and then sync my changes up to live through SVN? What about the DB? When I make quick changes to the stylesheet or a plugin, will I be jumping hoops just to get them launched?

    I’d be interested in an article explaining this in more detail. But for situations where I’m the sole programmer, I find it just as convenient to edit over FTP in a dev directory, and then rsync it with a live directory.

  9. There’s several ways to go about doing this.

    bq. Is the site itself the repository? Or is the site a checkout of the repository?

    No. Subversion stores files in an opaque format that webservers can’t read. It would be a checkout.

    bq. Am I going to need to run a server on my local machine, and then sync my changes up to live through SVN?

    The easiest way is if you have an external Subversion server that the production server can access, then all you need to do is `svn up` from inside the public html directory.

    However, I do manage a website that has a local repository that’s not web readable. In this case, I use `svn export` to create a tarball of the website, upload it, and extract, overwriting previous files. (an extra note: I usually tag these like DEPLOY-DATE). It’s slightly clunky though, I strongly recommend a public SVN server.

    bq. What about the DB?

    It is a tricky issue. My recommendation, based on the way MediaWiki does it, is to try to keep your database as stable as possible. When you do need to change it, make sure that you make a update.php file that can detect what version of the schema you’re using and update accordingly (run from shell, of course).

    bq. When I make quick changes to the stylesheet or a plugin, will I be jumping hoops just to get them launched?

    For an external SVN server, all you need to do is `svn up` and the changes are live (if the repository and the webserver are on the same server, you can setup a post-commit hook to instruct the webserver to update. I have this setup on another of my websites).

    Internally speaking, you could just upload just the file real fast, but I’d recommend tagging that snapshot anyway so that you can redeploy all the files if necessary.

    bq. I’d be interested in an article explaining this in more detail

    Read the “Subversion Book”:http://svnbook.red-bean.com/

    bq. But for situations where I’m the sole programmer, I find it just as convenient to edit over FTP in a dev directory, and then rsync it with a live directory.

    You should always use version control, even on single person projects. I always use version control on all of mine. 😉

  10. I strongly recommend any kind of version control. Especially Subversion. Heck, I even use it for non-programming related stuff: short stories, configuration files…

    In that sense, this is good advocacy. However, anyone who’s already using Subversion will find this article kind of useless. I for one would be interested in seeing a survey of managing non-versionable properties, like database schemas/formats and external environments (PHP 4.3.11 vs 4.3.10 can be a real bugger to fix).

  11. Well written — what a relevant topic!

    I can’t tell you how many times I’ve had the sinking feeling of version OUT-OF-control. Sadly, it was usually because I opted not to use a perfectly usable system that was already in place. Part of my battle with version control is _controlling the developer_ (in this case, myself) and getting them comfortable with checkin/checkout as part of their normal work flow.

  12. *Mike*: I think Edward’s explanation was pretty much spot on. When I’m deploying a website, I use Subversion more or less just like I’d use rsync.

    I have Apache/PHP/MySQL (or Django, or Rails, etc.) running locally on my home computer, with a virtual host pointing at the trunk of my working copy. As I work, I use Subversion to manage the important changes to the code, committing or rolling back as necessary. When I’m ready to deploy my changes to the production server, I make sure that everything locally is safely committed, and then *tag* the current revision as “YYYY-MM-DD_Deployment”.

    Pushing out my changes to production is then a pretty trivial task. I ssh into the production server, navigate to the document root, and check out that tagged release by running *svn co*. That merges all the changes into production, so all that’s left is to test one last time to make sure everything worked, and then you’re good to go.

    This is generally _faster_ for me than uploading changes via FTP, because I don’t have to play around in various directories trying to remember all the files I changed. The repository keeps track of that information _for me_, all I have to do is ask it nicely.

    The value added by _always_ being able to roll back to a previous release by checking out the previous tag is immense. It does _sound_ like a little extra work, but the overhead is minimal. I find that working through this process, even for one-off changes, quickly fades into the background.

    As an aside, if you do use Subversion to deploy your sites, I’d suggest reading “Preventing SVN Exposure”:http://hivelogic.com/articles/2006/04/30/preventing_svn_exposure to make sure you’re not inadvertently making sensitive information available.

    *Edward*: I agree with your assessment of the article; it’s very much focused on advocating the use of revision control to people who currently aren’t using it. Unfortunately, that’s a _huge_ group of people.

    *Walter*: You’re right! It’s a habit you’ve got to adopt to get the most benefit. That said, even only _periodically_ committing your files back to a repository is better than never using it in the first place. 🙂

  13. Subversion lets you create hooks on various actions including post-commit. Using that, it’s fairly trivial (for someone with reasonable perl or shell ability) to automatically update your website each time you ‘tag’ a release, and update a staging website each time you commit.

    Running your website as a checked-out repository might not be a good idea due to the svn cruft lying around (make sure your setup doesn’t allow viewing of ‘hidden’ files and directories)

  14. While I’m here, let me say that the headline was a poor editor decision: the article is abour revision control, not buttons.

    Back in April Slashdot talked about the way “headlines have changed”:http://slashdot.org/article.pl?sid=06/04/09/035205 from being ‘sensational’ to being descriptive: online we’re hit by so much information you need to put some info in the headline to grab our attention rather than just making it ‘loud’.

    In this case, figuring ALA knew this, I guessed this was an article about buttons. Oh well .. great article anyway 🙂

  15. I totally agree to Rene that working with some kind of version control system should be in the university schedule of computer science students. I (as an employer) often find young applicants for my job positions never ever have worked in a team and they don’t even know what version control is good for. I really get a headache if I see them working on their local drive with no backup at all. I used to work in some 100+ people projects so I know the need of version control. But even if you have a version control system installed developers will need to use it in a proper way. For example if you move files to another directory some copy the files and delete the old ones. So all the history is gone (ok, it’s still there, but difficult to compare).

  16. @Edwards: subversion has a WebDAV interface, which make it comfortable to use with Dreamweaver.
    Dreamweaver sees the repos as usual with FTP.
    Every ‘upload’ will generate a commit. You lost the possibility to make custom commit messages, but I think it’s still an interesting use because it integrates itself smoothly in your workflow.

    It would be great if Adobe will integrate Dw with svn, i.e. using Design Notes as commit.messages

  17. I am as loyal a fan of subversion as you’ll find, but in my office, we frequently run into the same version-control wall.

    Our graphic designers, who also need to do a bit of template editing, are not command-line saavy in the least, and they work exclusively on OS X. Our developers all use TortioseSVN on windows (or the command line on the Mac) to access our repository, but the designers – ha! fuggedaboudit.

    So we’ve tried to find a GUI client they can use. I’ve checked out svnx, smartsvn, scplugin, and others, and all of them suffer from the same problem: when initially checking out a branch from the repository over the network, at some point during the checkout (not always in the same place) they will hang and we’ll be stuck with a spinning beach ball interminably.

    Apart from apache integration, is there a working GUI for our Mac-only designers?

  18. I’m a relatively new user of SVN, and my favorite way to use it in Windows is Tortoise (mentioned already), which integrates SVN into the Windows GUI with contextual menus, etc.

    Alas, there is nothing quite as good as Tortoise for OSX, but “SCPlugin”:http://scplugin.tigris.org/ comes pretty close. Finder integration, file status badging, etc. It doesn’t support every feature, but includes most that you will use on a daily basis.

    Also, I wanted to note that “BBEdit”:http://www.barebones.com/products/bbedit/ has fantastic SVN support.

  19. *Rick*: First, I agree with you about the article title. It sounded light and fun when I wrote it, but it does turn out to be less than informative as to the article’s content. Next time, I’ll think about it a little harder (and I do hope there’s a next time… 🙂 ).

    Second, the hooks that Subversion provides are nothing short of brilliant. I hadn’t thought about using them to automatically deploy based on tags, but it’s a wonderfully simple concept! I’d take it a step further, and perhaps define certain _types_ of tags that would auto-deploy to distinguish tagging a certain point in development (e.g. “ALMOST-DONE-WITH-2.1”) from tagging a release (e.g. “RELEASE-2.1”).

    *Andreas*: Moving files and directories is the main reason I switched from CVS to Subversion a year or two ago. You’re absolutely correct in saying that being able to easily keep the contextual revision information without needing to remember that this file _used to be_ that other file is stunningly valuable.

    *Flavio*: The WebDAV interface is a nice feature, especially when used on a repository that’s set the *SVNAutoversion* property. There’s “even a movie demonstrating that feature”:http://weblog.textdrive.com/article/92/holy-auto-subversion-batman if you can believe it. It negates a little bit of the contextual benefit, since saving a file via WebDAV doesn’t offer the chance to add a useful message along with your commit, but you can get around that to some extent through judicious use of tags.

    *Danny*: The Finder plugin that John-Paul mentions is an option that kinda sorta resembles TortiseSVN. It isn’t quite as elegant, but it’s better than nothing. I’m hoping that others will contribute some GUI ideas, because I’m strangely in love with the command line and don’t have much visibility into the pretty tools that other people run off with. 🙂

    *John-Paul*: You’re right, BBEdit supports SVN quite well, as does TextMate, Xcode, Eclipse, and a host of other editors. Leveraging the editor that you already know and love is probably the single easiest way to get into revision control.

  20. I did that once, on a UNIX server at work, with an unlabled blue button. I didn’t even press it, just touched it.

    It was the reset button. Oops.

  21. I did that once, on a UNIX server at work, with an unlabled blue button. I didn’t even press it, just touched it.

    It was the reset button. Oops.

  22. Mike,

    Thanks for the great article.

    Any ideas on using subversion as the storage layer of a wiki like TWiki? For example, TWiki uses RCS. But RCS is the predecessor of CVS, and CVS the predecessor of subversion.

    I’m thinking of using Kupu as a WYSIWYG html editor and PHP or (if I must learn it) Python to hook into Subversion. Hence, a modern wiki for our documentation.

  23. *Kris*: I didn’t mean to make it sound like Subversion is the _only_ option, but I do believe that Subversion is probably the _best_ option for anyone who’s just starting out with revision control. It’s an open source program, meaning that no one needs management’s clearance to purchase it and start running, it’s ported to just about every operating system out there, and it’s drop dead easy to install and use. “Perforce”:http://www.perforce.com/index.html, “Bitkeeper”:http://www.bitkeeper.com/, and other commercial revision control systems are certainly _powerful_, but they’re nowhere near as _obtainable_ as Subversion.

    As far as CVS goes, I consider Subversion to be it’s complete replacement. Subversion fixes some of the annoying facets of CVS that I consider bugs (moving change logs along with files, storing directory revisions and properties, atomic commits, and more). For every project I’ve worked on in the last year or two, Subversion has simply been the better choice. The article, I think, reflects that. 🙂

    *Andrew*: I don’t have any experience using Subversion directly as a store for a wiki. It sounds like an interesting idea. 🙂 I currently run “dokuwiki”:http://www.splitbrain.org/projects/dokuwiki locally as a braindump, which stores all of it’s information in flat files which I rsync to a remote server nightly. The wiki takes care of diffs internally, so I haven’t worried too much about external revision control.

  24. Hey there, just wanted to add that there is a small typo in the article. The software is called “tortoise”, not “tortise” 😉 Excellent article btw, as always!

  25. For GUI clients, I have been using SvnX, which is ok. It does what I need it to do, but as Danny mentions is still not very good for someone who doesn’t like the command line. The designer I work with doesn’t know where to start.

    Has anyone tried the plugin for Quicksilver? I just activated it, but it seems quite promising.

  26. I tried SVN (+ TortoiseSVN) twice, and it just didn’t do it for me. It’s not that it didn’t have enough features, it’s almost like it had too many features.

    I expected something easier. I want something that sits in the background and perhaps records the state of my sauce code at given intervals (seconds, minutes, hours, maybe even keystrokes, I don’t know), and all this gets stored in a nice database that keeps track of the changes for me and allows me to restore them. Ideally this would be automated and I wouldn’t have to give an order to save my work. As a single developer this is all I need; to go back in time.

    SVN proved to be too much for me. I found that I could just as easily copy/paste my source code files to a directory every once in a while and save it. Maybe if I ever work with somebody this will change.

  27. I use SVN on Dreamhost account to keep files away in case of hdd crash or something and to be able to connect and work in many locations. I’m the only editor of those files, but it’s great to move back in time to restore a piece of code I was sure won’t be necessary any more. The Subclipse plugin for Eclipse makes it very easy.
    At work we use CVS for teamwork synchronization and it does good job as well. It makes life easier, but doesn’t solve the human factor. Everyone in the team has to commit every change as soon as it’s done, not “when I’ll finish the changes I’m going to do tomorrow”

  28. No matter what form of version control one uses, you are only halfway there unless you have a decent hierarchical storage/backup system. I spent a goodly portion of my IT career in storage mangement, and in some cases had to recover DB instances for our version control software to a previous date (ok, we recovered it to a shadow system, extracted what was needed, and updated the online VCS, with the data needed)
    Of course you may not have the luxury of a large disk farm with HSM software and a robotic tape library, but reasonable solutions can be implemented at even the single server level.
    Disk and tape are cheap, when compared to the man-hour cost of lost time.
    That’s my take on it (yes, I’m an operations/hardware kind of guy, well..was, retired this year after 33 years in IT)

  29. Two months ago, I would just skip this article, labeling it “too techie”. But then, some of my co-workers started talking about Subversion, and last week we started using it. And yes, it’s great! Whenever those programming bastards mess up my CSS, I can point right to the guilty one and give him a good ol’ spanking!

  30. If you spend a lot of time on a laptop without Internet access–even if you just take the train to work every morning–“svk”:http://svk.elixus.org/ can be very handy. It’s a program that interfaces with a Subversion repository, but it mirrors all the history on your own disk, allowing you to check changes into your local repository even when you don’t have Internet access (like when you’re traveling). You can later synchronize with the central copy of the repository. Since you have all the history with you, you can do all the neat back-in-time stuff you’d normally need access to the server to do. And it lets you keep long projects in local branches that nobody else can screw up. Very useful all around.

  31. If you spend a lot of time on a laptop without Internet access–even if you just take the train to work every morning–“svk”:http://svk.elixus.org/ can be very handy. It’s a program that interfaces with a Subversion repository, but it mirrors all the history on your own disk, allowing you to check changes into your local repository even when you don’t have Internet access (like when you’re traveling). You can later synchronize with the central copy of the repository. Since you have all the history with you, you can do all the neat back-in-time stuff you’d normally need access to the server to do. And it lets you keep long projects in local branches that nobody else can screw up. Very useful all around.

  32. Great article. And you’re right to choose Subversion since it is definately one of the best things since sliced bread.

    Even tagging and branching are easy – for Luke Bussey above, just create two small scripts which give you the command lines to branch from the trunk and tag on the branch. Consistency is the key.

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA