<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Northern Binary &#187; Version Control</title>
	<atom:link href="http://blog.northernbinary.org/category/version-control/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.northernbinary.org</link>
	<description></description>
	<lastBuildDate>Thu, 11 Mar 2010 10:16:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>svn:externals</title>
		<link>http://blog.northernbinary.org/programming/svnexternals/</link>
		<comments>http://blog.northernbinary.org/programming/svnexternals/#comments</comments>
		<pubDate>Fri, 05 Oct 2007 07:06:07 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://blog.opject.org/?p=7</guid>
		<description><![CDATA[I just love svn:externals. Well, I just love Subversion actually. But I love svn:externals in particular. I can split my life basically into two parts. Life before svn:externals and my life after svn:externals. Nah, thats a bit of nonsense of course, but svn:externals has made a big impact on how I organize my source code [...]]]></description>
			<content:encoded><![CDATA[<p>I just love <code>svn:externals</code>. Well, I just love Subversion actually. But I love <code>svn:externals</code> in particular. I can split my life basically into two parts. Life before <code>svn:externals</code> and my life after <code>svn:externals</code>. Nah, thats a bit of nonsense of course, but <code>svn:externals</code> has made a big impact on how I organize my source code or even more important, how I organize my dependencies.</p>
<p>If you&#8217;re a programmer, be it with ActionScript, ColdFusion, Java or whatever, then I&#8217;m sure you have worked with external libraries, packages or frameworks before. A common practice is to make a copy of your framework, packages or libraries (called dependencies from now on) into your projects source folder and take it from there. Sometimes your development environment allows you to include a certain set of folders in a search path so you don&#8217;t have to make an explicit copy of your dependencies but allows you to place these shared dependencies in a single place to be used by many from then on.</p>
<p>Although this works for most of us pretty well most of the time, at some point things will start to fall apart. Imagine you store your dependencies and your projects separate from each other in your Subversion repository and your dependencies are checked out on your drive in a generic location. This saves you from making explicit copies of your decencies and it prevents you from updating the same bug in your framework 25 times because the same dependencies are shared by 25 different projects. So, separating your projects and your dependencies is a good thing you would say.</p>
<p>The problem is, however, that the code base of dependencies usually change over time. Libraries and frameworks are patched and updated with bug fixes that might have an impact on the interface and break the projects that depend on them. A more dangerous situation is when the updates of dependencies have only changes that are invisible. An upgraded framework might still compile. However, if you do not put your product through the same rigorous testing as with the previous version of your framework, you can never be sure it will actually work and that it hasn&#8217;t introduced new bugs. When you share dependencies then maybe an update is not what you want for all your projects but just for some. So what do you do? The explicit copy helps in this situation because every project can use its own version of a set of dependencies.</p>
<p>So then, what is it? Sharing or explicit copies?</p>
<p>Neither actually. Unless you are a &#8220;serial tagger&#8221; and make a tag of every single version of the dependencies trunk for every single project. This is usually not the case and if you&#8217;re working in an environment where you&#8217;re not involved with every single project you need another strategy. Allow me to introduce: <code>svn:externals</code>.</p>
<p>With <code>svn:externals</code> you actually have a sort of hybrid situation. You make an explicit copy of your dependencies in your project source folder while still having a shared situation at the same time. You still follow? Basically you could compare <code>svn:externals</code> to what they call a <code>symbolic link</code> in a UNIX environment.</p>
<p>Imagine you&#8217;re building a website that incorporates a CMS and you want to use this CMS as part of your project. The CMS is located in the Subversion repository in the <code>resources</code> folder and has a number of tagged versions associated with it. Your project is located in the same repository in the <code>projects</code> folder and lives in the <code>trunk</code> folder. This might look something like this:</p>
<pre class="code box">
+repository
  +resources
    +mycms
      +branches
      +tags
        +1.0.0
        +1.0.2
        +1.5.0
      +trunk

  +projects
    +myproject
      +branches
      +tags
      +trunk
        +deploy
        +source
</pre>
<p>This seems all pretty standard. In the <code>trunk</code> folder of the project you see two other folders, a <code>deploy</code> and a <code>source</code> folder. This is how I personally divide most of my projects. Everything in the <code>deploy</code> folder goes straight onto the server. The <code>source</code> folder contains everything that needs compilation, like Flash files and Word documents that need to be converted into PDF format. Anything compiled or published in this <code>source</code> folder will be automatically placed in the <code>deploy</code> folder. Be it with application publish settings or through Ant or MAKE files.</p>
<p>We want our CMS to be part of our <code>deploy</code> folder because it&#8217;s written in PHP and it doesn&#8217;t need any special kind of compilation. So, we checkout the <code>trunk</code> folder of our project and place it somewhere convenient on our hard drive. The checked out project folder should now contain both the <code>deploy</code> and the <code>source</code> folders.</p>
<p>Now its time for <code>svn:externals</code> to do its magic. We are going to add a SVN property to the <code>deploy</code> folder of our checked out copy. If you haven&#8217;t used SVN properties yet, like <code>svn:keywords</code>,  then I suggest you go have a read in the excellent <a href="http://svnbook.red-bean.com/en/1.0/ch07s02.html" onclick="javascript:pageTracker._trackPageview ('/outbound/svnbook.red-bean.com');">online Subversion book</a> to get up to speed.</p>
<p>By adding the <code>svn:externals</code> property you can create an external link to another location in your repository. As a matter a fact, you can create an external link to a location in a completely different repository on a completely different server that&#8217;s somewhere on the other side of the world. The files at the external location will then be included in your project as if they are part of your project through what might be compared to as a symbolic link. In a sense the external files are part of your project since the files that are external will be checked out on your hard drive just as any other files of your project. Now, if someone else would make changes to these external files and would commit those changes, the next time you do an SVN update on your project you will receive those changes as well. As you might understand this is a very powerful feature of Subversion because you can contain all your project dependencies in a single place while still having the ability to update from a single place at the same time.</p>
<p>Back to our repository example from before. If we want to have our project depend on version 1.5.0 of the CMS then all we have to do is create a <code>svn:externals</code> property on the <code>deploy</code> folder of our project pointing to the tagged 1.5.0 version of our CMS. Even if the <code>trunk</code> of the CMS changes with bug fixes and other patches, it has no impact on our project. Unless we explicitly change the <code>svn:externals</code> property to point to a newer version, we&#8217;re safe.</p>
<p>Setting the <code>svn:externals</code> property is not much of a issue. Most GUI clients like TortoiseSVN and Subclipse for Eclipse support setting Subversion properties. The <code>svn:externals</code> property consists of a variable name and a URL value. In our example we could set the <code>svn:externals</code> property on the <code>deploy</code> folder to the following value:</p>
<pre class="box code">mycms svn://svnserver/repos/resources/mycms/tags/1.5.0</pre>
<p>After setting the <code>svn:externals</code> property you have to run a SVN update on your checked out project and you should receive the external files as part of your project (If you&#8217;re using Subclipse you even get to see an special link symbol on the folders icon). If you need more than one <code>svn:externals</code> property on a single folder then you can add as many values to the <code>svn:externals</code> property as you like.</p>
<p>Hopefully all this make sense and that <code>svn:externals</code> will be useful to your projects. If you need more in depth information on the subject then I can highly recommend the <a href="http://svnbook.red-bean.com/en/1.0/ch07s03.html" onclick="javascript:pageTracker._trackPageview ('/outbound/svnbook.red-bean.com');">online Subversion book.</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.northernbinary.org/programming/svnexternals/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
