Better Branching in Subversion

2010
03.04

There are many perils involved with grafting your toes to your armpits. First of all, toes are meant to be connected to your feet – not placed in your armpits where it is both uncomfortable, and smelly. Aside from the olfactory stink, you also lose the benefit of being able to maintain good balance while walking. What might have seemed like a good idea at first is obviously a bad bio-engineering decision.

Grafting another arm onto your torso might have some merit as it isn’t just a sub-subsection of a given trunk (read: your leg); it’s actually a full trunk unto itself, which means you get more use out of it. About now you might be wondering what grafting of toes and arms has to do with tech. Besides the nifty bio-tech opportunities, it serves as a good metaphor for branching practices in Subversion.

I’m sure by now most of you have had an opportunity to create a branch and work with it. It’s a pretty simple affair; nothing more than a copy of one directory in subversion to another. For example:

svn copy trunk branches/branch-name

Subversion branches are great because they are cheap. Not cheap like the US Dollar; we’re talking practically free. Whether you are branching a deep tree or a shallow tree, it’s all the same (cheap) operation to subversion.

Branching Correctly and Why it Matters

The temptation with using branches is to only branch the directory that you are going to be working in instead of the complete trunk directory. While that might seem like a great idea, it really isn’t. By doing so, you make it much more difficult to merge safely. More importantly, you lose valuable contextual data.

Let’s say you want to work only in the /baz sub-directory of ../trunk/foo/bar (i.e., ../trunk/foo/bar/baz). If you branch only that directory, you have created two problems:

  1. /baz loses its context within the /trunk/foo/bar codebase. This means that it would not be immediately clear to someone looking at your branch where it was branched from. (note: there are means of figuring it out, but that’s not the point)
  2. if you find you need to make changes above /baz, you’ll have to create a new, independent branch.

This is where the value of cheap branching becomes clear. When you branch, subversion doesn’t actually copy any files, all it does is note a new directory in the branches directory and that it should contain the same data as the directory you branched from (effectively, it’s like a symlink in unix land). From there on out any change you make is stored against that branch, but only just changes. This is why branching is cheap; it doesn’t take up physical space until you make changes.

Perhaps you’re thinking, “I don’t care about how much space it takes up – I just don’t need to deal with the extra directories under trunk!” While that is a valid argument, keep in mind that what you gain in perceived simplicity, you lose in both flexibility and context.

Making Branches Work For You

We know it’s probably not a good idea to branch a sub-directory of the trunk; but, that still doesn’t help us when we only want that sub-directory. Have no fear; there is a simple solution: After branching off of the trunk directory, checkout the sub-directory you want from the branch.

As an example, say we want to create a branch of /trunk called “foo-widget” but we only want the /trunk/foo/bar sub-directory to work in. Here’s how you would do that:

svn copy https://domain.tld/svn/trunk https://domain.tld/svn/branches/foo-widget
svn co https://domain.tld/svn/branches/foo-widget/foo/bar bar

This would first create a branch of the trunk directory called “foo-widget” and then checkout the sub-directory /foo/bar from the “foo-widget” branch into a local directory called ‘bar’. This allows maximum flexibility to switch gears and work on a different path in the branch should the need arise, while maintaining the simplicity you are looking for; and, more importantly, the desired consistent contextual path information for everyone who might look at this branch.

SVN and Automatic Keyword Expansion Setup

2010
03.04

So in order to ensure that $Id$ keyword expansion happens on new files that enter subversion, it’s necessary to make some configuration changes to your subversion client. Those people using TortoiseSVN can change their svn config file by doing the following:

  1. Right click on any Windows Folder
  2. Select TortoiseSVN->Setting
  3. Click on the ‘Edit’ for Subversion configuration file (which will open the configuration up in Notepad, or something similar).

Unix users can find their config file located in $HOME/.subversion/config and can use any of vim, emacs, nano or pico to edit the configuration (or whatever your personal flavor of editor is).

In either case, once you have opened the file, search for the sections [miscellany] and [auto-props] and then use what follows to make your configuration look similar.


[miscellany]
enable-auto-props = yes

[auto-props]
*.php = svn:eol-style=native;svn:keywords=Id
*.pl = svn:executable;svn:keywords=Id
*.sh = svn:eol-style=native;svn:executable;svn:keywords=Id
*.txt = svn:eol-style=native
*.png = svn:mime-type=image/png
*.jpg = svn:mime-type=image/jpeg
*.gif = svn:mime-type=image/gif
*.xml = svn:eol-style=native
*.xsl = svn:eol-style=native
*.xsd = svn:eol-style=native
*.html = svn:eol-style=native
*.css = svn:eol-style=native;svn:keywords=Id
*.js = svn:eol-style=native;svn:keywords=Id

This sets a couple of svn properties when adding files of the types listed above:

  • Adds keyword “Id” (aka $Id$ expansion) to .css, .js, .pl, and .sh files (we can do this for more files if you guys want).
  • Set’s the end of line style (CRLF for windows, LF for *nix) to native for every textual file listed (meaning when a windows user checks out the file, they get it normalized to CRLF and a nix user get’s normalized to LF – the normalization happens transparently by your subversion client and internally in the repository they are stored using LF).
  • Some files are automatically marked as executable (perl and shell script files)
  • Images have their mime-type set appropriately so that subversion knows that files containing those extensions (.gif, .png, .jpg) are binary type files. This has an added benefit of allowing the subversion apache module to send the correct Content-Type header for the file without having to guess.
Comments Off

Private vs. Protected Members/Properties

2006
03.24

So it’s been a while since I last posted anything and I just found this interesting page with an algorithm for choosing the correct scope for a class member/property – figured I’d share it for anyone interested:

Pretty much every object oriented programming language let’s you set the visibility of object members. Usually it defaults to public. That means everybody can access that member. Of course often you don’t want to [allow] other objects to access certain parts of your object. This is where private or protected come in to play.

— see: Michiel “El Muerte” Hendriks for more…