1. SVN Externals and Relative Links

    Last week I encountered a limitation with using externals in SVN. It shows up when you are using the svn:externals property to bring a folder into your working copy, and when the folder you are bringing in uses the svn:externals property to bring in another folder whose path is no longer valid. In my case, the problem was caused by the second external referring to a path with an absolute link instead of a relative link – the absolute link was no longer valid.

    Here’s an example.

    Let’s say you have a project called Pizza which has the svn:externals property set to bring in a folder Pepperoni from revision 4500. The property looks like this:

    -r 4500 http://server_name/meals/pizza/toppings/peperroni Pepperoni

    And let’s say you want revision 4500, because the head of the trunk is at 4900, and features that were added to Pepperoni between 4500 and 4900 do not apply to the new Pizza project. The unique thing about the Pepperoni project is that it has subfolders for different spices and flavors: Salt, Pepper, and Smoke. The Smoke folder happens to be using the svn:externals property, and it looks like this:

    -r 3222 http://server_name_old/meals/pepperoni/spices/smoke Smoke

    Again, you want revision 3222, because features that were changed between 3222 and the 4900 (the top revision of the trunk) do not apply to your Pizza project.

    If you noticed the difference in paths, you’ll see the external for the Smoke folder is using an old name of the server. Sometime between version 3222 and 4500, the server’s name changed from ‘server_name_old’ to ‘server_name’. Because of this, when you commit your Pizza project (with the svn:externals property set to bring in Pepperoni), the subfolder of Pepperoni, Smoke, which is being externalled in at a second level, will not see the old server name.

    Because the svn:externals property applied to Pepperoni occurred back in time (at revision 3222), you can only correct the invalid absolute path by copying revision 3222 of Pepperoni to a branch, and adjusting the externals property to use the new server name. You wouldn’t want to keep it in the trunk as you’d lose the changes made between 3222 and 4900 (the head).

    The URLs I show in the svn:externals above are absolute. In Subversion 1.5, relative externals were introduced, which allow you to external in a folder without naming the server. Here is the correct external, which uses a relative path to the repository root (without the server name):

    -r 3222 ^/meals/pizza/toppings/peperroni Smoke

    Using relative links with the svn:externals property will prevent broken external properties that happen as a result of dead (invalid) paths.