<?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>Cranky Bit &#187; Subversion</title>
	<atom:link href="http://blog.crankybit.com/tags/open-source/svn/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.crankybit.com</link>
	<description>Take a byte out of tech!</description>
	<lastBuildDate>Wed, 09 Mar 2011 17:23:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Separating a Large Repository</title>
		<link>http://blog.crankybit.com/separating-large-repo/</link>
		<comments>http://blog.crankybit.com/separating-large-repo/#comments</comments>
		<pubDate>Tue, 04 Nov 2008 12:52:45 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Batch Scripting]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/?p=312</guid>
		<description><![CDATA[A few months ago, I posted an article about combining multiple Subversion repositories into one large repository. Some folks have expressed an interest in doing the opposite--separating one large repository into multiple smaller repositories. The process is not without its quirks, but it can be done. At first glance, you'd conclude the process would work [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago, I posted an article about <a href="http://blog.crankybit.com/combining-repos/">combining multiple Subversion repositories into one large repository</a>. Some folks have expressed an interest in doing the opposite--separating one large repository into multiple smaller repositories. The process is not without its quirks, but it can be done.</p>
<p>At first glance, you'd conclude the process would work much the same way: Loop through the individual directories in the large repository, create smaller repositories for each one, then dump and import the contents of each directory into its small repository.</p>
<p>The tricky part is that the Subversion dump command dumps everything in the repository, by revision. In order to pull just a single directory, you must filter a complete dump with the "svndumpfilter" command. <a href="http://allmybrain.com/2007/10/15/using-piped-svndumpfilter-commands-to-separate-an-svn-repository/" target="_blank">This blog post</a> by <a href="http://allmybrain.com/" target="_blank">AllMyBrain.com</a> basically explains how to accomplish this in Linux. I usually have to work on a Windows box on the job, so I wrote up a script to accomplish this in a Windows batch script.</p>
<p>The strategy is the same as the Linux script, though. We're going to use "svnadmin dump" the large repository, then use "svndumpfilter" to filter by just the directory we want, then "svnadmin load" the results into the newly created repository. All of this can be combined into a single statement via piping:</p>
<div class="igBar"><span id="ldos-3"><a href="#" onclick="javascript:showCodeTxt('dos-3'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">DOS:</span>
<div id="dos-3">
<div class="dos">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">svnadmin dump c:\my\large\repo\ |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">svndumpfilter include MyDirectory |</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">svnadmin load MySmallRepo\MyDirectory </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>This will make a little more sense when we look at the full script. Let's just put it out there and then go through it.</p>
<div class="igBar"><span id="ldos-4"><a href="#" onclick="javascript:showCodeTxt('dos-4'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">DOS:</span>
<div id="dos-4">
<div class="dos">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/set.html"><span style="color: #b1b100; font-weight: bold;">SET</span></a> <span style="color: #448844;">SmallRepoPath</span>=c:\SmallRepos</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/set.html"><span style="color: #b1b100; font-weight: bold;">SET</span></a> <span style="color: #448844;">PathToRepo</span>=c:\BigRepo</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/set.html"><span style="color: #b1b100; font-weight: bold;">SET</span></a> <span style="color: #448844;">UNCToRepo</span>=file:///c:/BigRepo</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/set.html"><span style="color: #b1b100; font-weight: bold;">SET</span></a> <span style="color: #448844;">PathToChkout</span>=c:\BigRepoChkout</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mkdir %<span style="color: #448888;">PathToChkout</span>%</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">svn co %<span style="color: #448888;">uncToRepo</span>% %<span style="color: #448888;">PathToChkout</span>% --ignore-externals</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/dir.html"><span style="color: #b1b100; font-weight: bold;">dir</span></a> /A:D /B %<span style="color: #448888;">PathToChkout</span>%&gt; %<span style="color: #448888;">PathToChkout</span>%\dirs.tmp</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/for.html"><span style="color: #00b100; font-weight: bold;">for</span></a> /F %%i <a href="http://www.ss64.com/nt/in.html"><span style="color: #00b100; font-weight: bold;">in</span></a> <span style="color: #66cc66;">&#40;</span>%<span style="color: #448888;">PathToChkout</span>%\dirs.tmp<span style="color: #66cc66;">&#41;</span> <a href="http://www.ss64.com/nt/do.html"><span style="color: #00b100; font-weight: bold;">do</span></a> <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <a href="http://www.ss64.com/nt/if.html"><span style="color: #00b100; font-weight: bold;">if</span></a> <a href="http://www.ss64.com/nt/not.html"><span style="color: #000000; font-weight: bold;">not</span></a> %%i==.svn <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.ss64.com/nt/echo.html"><span style="color: #b1b100; font-weight: bold;">echo</span></a> Processing &quot;%%i&quot;...</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; mkdir %<span style="color: #448888;">SmallRepoPath</span>%\%%i</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; svnadmin create %<span style="color: #448888;">SmallRepoPath</span>%\%%i</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; svnadmin dump %<span style="color: #448888;">PathToRepo</span>% | svndumpfilter include %%i | svnadmin load %<span style="color: #448888;">SmallRepoPath</span>%\%%i</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">del %<span style="color: #448888;">PathToChkout</span>%\dirs.tmp</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">rmdir /S /Q %<span style="color: #448888;">PathToChkout</span>% </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>First, we're setting our paths. "SmallRepoPath" will be the directory holding all of the small repositories we'll be creating. "PathToRepo" and "UNCToRepo" point to the big repository as DOS and UNC paths, respectively. "PathToChkout" points to a Subversion checkout of the large repository.</p>
<p>First, we check out the large repository with the "svn co" command. We do this just so that we can call the "dir /A:D /B" command, which says, "List just the directories in the checkout directory." We use that output to loop through each directory in the large repository.</p>
<p>Then, for each directory in the large repository, we create a corresponding small repository, then do our dump/filter/load combo. Again, we're dumping the contents of the large repository, using "svndumpfilter" to filter by directory, then loading that filtered dump into the new small repository.</p>
<p>Finally, we just do some cleanup by removing our temp files and the checkout directory.</p>
<p><strong>There <u>are</u> a few caveats with this code.</strong> </p>
<p>First, it will import <em>all</em> of the large repository's revisions into the smaller repository. There are svndumpfilter arguments to prevent this, such as --drop-empty-revs and --renumber-revs, but I found the Windows Subversion binaries to be problematic with these arguments. The end result is that you have more revision numbers than needed, but only the relevant data is actually imported into the repository, and viewing logs on just the imported directory will still obviously show revision logs related to that directory, so there's really little harm done.</p>
<p>Second, the dump/filter/load action doesn't always work on a directory that has been moved (copied/deleted) from another location within the large repository. What's worse, it won't <em>fail,</em> it just won't load any data into the small repository. To address this, use the --revision argument on the "svnadmin dump" command to do a dump starting at a revision after the move took place. Doing so will give the "svndumpfilter" command something it can work with.</p>
<p>This process is certainly more complicated to <em>explain</em>, but ultimately there's not that much more going on. Hopefully this explanation is helpful to you.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/separating-large-repo/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Combining Repositories Into One Large Repository</title>
		<link>http://blog.crankybit.com/combining-repos/</link>
		<comments>http://blog.crankybit.com/combining-repos/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 05:44:58 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Batch Scripting]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/?p=299</guid>
		<description><![CDATA[I keep all my projects in separate Subversion repositories. I did this because it feels a lot cleaner this way, there is less risk in the event of repository corruption, and I use corresponding Trac projects that I also wanted to keep separate from one project to the next. That said, there are advantages to [...]]]></description>
			<content:encoded><![CDATA[<p>I keep all my projects in separate Subversion repositories. I did this because it feels a lot cleaner this way, there is less risk in the event of repository corruption, and I use corresponding Trac projects that I also wanted to keep separate from one project to the next.</p>
<p>That said, there are advantages to having one single repository. No big deal, that can be done after the fact with code.</p>
<p>Here is some Windows code to combine all the repositories in a directory into a single big repository:</p>
<div class="igBar"><span id="ldos-6"><a href="#" onclick="javascript:showCodeTxt('dos-6'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">DOS:</span>
<div id="dos-6">
<div class="dos">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/set.html"><span style="color: #b1b100; font-weight: bold;">set</span></a> <span style="color: #448844;">svndir</span>=c:\Test\svn</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/set.html"><span style="color: #b1b100; font-weight: bold;">set</span></a> <span style="color: #448844;">bigrepo</span>=c:\Test\BigRepo</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/set.html"><span style="color: #b1b100; font-weight: bold;">set</span></a> <span style="color: #448844;">bigrepoUNC</span>=file:///c:/Test/BigRepo</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/set.html"><span style="color: #b1b100; font-weight: bold;">set</span></a> <span style="color: #448844;">rev</span>=<span style="color:#800000;">0</span>:HEAD</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/echo.html"><span style="color: #b1b100; font-weight: bold;">echo</span></a> Setting up the big repository.</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">rmdir /S /Q %<span style="color: #448888;">bigrepo</span>%</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mkdir %<span style="color: #448888;">bigrepo</span>%</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">svnadmin create %<span style="color: #448888;">bigrepo</span>%</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/cd.html"><span style="color: #b1b100; font-weight: bold;">cd</span></a> %<span style="color: #448888;">svndir</span>%</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/dir.html"><span style="color: #b1b100; font-weight: bold;">dir</span></a> /A:D /B&gt; dirs.tmp</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/for.html"><span style="color: #00b100; font-weight: bold;">for</span></a> /F %%i <a href="http://www.ss64.com/nt/in.html"><span style="color: #00b100; font-weight: bold;">in</span></a> <span style="color: #66cc66;">&#40;</span>dirs.tmp<span style="color: #66cc66;">&#41;</span> <a href="http://www.ss64.com/nt/do.html"><span style="color: #00b100; font-weight: bold;">do</span></a> <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.ss64.com/nt/echo.html"><span style="color: #b1b100; font-weight: bold;">echo</span></a> Adding %<span style="color: #448888;">svnDir</span>%\%%i to the big repository:</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">svnadmin dump -r %<span style="color: #448888;">rev</span>% %%i &gt;&nbsp; %%i.dmp</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">svn mkdir -m &quot;Making project directory %%i.&quot; --non-interactive %<span style="color: #448888;">bigrepoUNC</span>%/%%i</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">svnadmin load %<span style="color: #448888;">bigrepo</span>% --parent-<a href="http://www.ss64.com/nt/dir.html"><span style="color: #b1b100; font-weight: bold;">dir</span></a> %%i&nbsp; &lt; %%i.dmp</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">del /F /Q %%i.dmp</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">del dirs.tmp </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>There's really not much happening here; the process is simple. First, we create the new "big" repository with the <strong>svnadmin create</strong> statement. Second, we loop through the directory, processing each Subversion repository in the directory with a three-step process: <strong>(a)</strong> Dump the repository with the <strong>svnadmin dump</strong> statement into a temporary *.dmp file. <strong>(b)</strong> Explicitly add a new directory in the "big" repository for the current repository we're processing, with the <strong>svn mkdir</strong> statement. <strong>(c)</strong> Import the dump into the "big" repository with the <strong>svnadmin load</strong> statement. Really, the rest of the code is just looping, commenting, or cleanup code.</p>
<p><em><strong>What have we produced?</strong></em> As you might expect, we now have one big repository that has all of the files and commits that were in all of the smaller repositories. The big repository will maintain its own revision numbering, so the revision numbers in your smaller repositories will not match the big repository's revision numbering, although the original <em>commit dates</em> will be preserved. This can be really handy for searching or similar actions that you might do from a more global perspective.</p>
<p>However, this approach is not without its caveats. During the import process, one entire repository is imported at a time. All of a particular repository's revisions will be "grouped" together in the big repository. As a result, revision numbers in the big repository will change every time you recreate it, if there was any new activity in the repositories it contains. For instance, revision #1050 in the big repository may parallel revision #500 in Repository X, but if a commit was added to a repository that is imported before it and the big repository is recreated, that revision would now be #1051. Additionally, although all history and dates are preserved in the revisions, the big repository has commits that are not in chronological order since the import was processed by repository. This inconsistent date/commit ordering can be confusing to some repository reporting tools and may actually render those tools useless to you when they are reporting by date.</p>
<p><em><strong>Filtering by revision. </strong></em>Note that my svnadmin dump statement includes the -r argument, which specifies the beginning and ending revisions to dump. By default, I'm using "0:HEAD", which basically means "dump every revision", or "dump from the first revision to the HEAD, or latest, revision". Changing the beginning and ending revisions can be useful, especially when used with <em>dates</em> instead of actual revision numbers. For instance, you could change the value to <strong>{2007-01-01}:{2007-12-31}</strong> to only dump revisions that were committed in 2007.</p>
<p>Combining all of your smaller repositories into one big repository after the fact isn't a perfect solution, but it can be handy, and it's really easy to do when you have a script like this ready to run.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/combining-repos/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>How to Fix 301 Error for Subversion Checkouts</title>
		<link>http://blog.crankybit.com/how-to-fix-301-error-for-subversion-checkouts/</link>
		<comments>http://blog.crankybit.com/how-to-fix-301-error-for-subversion-checkouts/#comments</comments>
		<pubDate>Mon, 23 Jun 2008 11:41:59 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[howto]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/?p=306</guid>
		<description><![CDATA[My Linux box was hosting Subversion with no problem. I added a new repository to the several that were already present, and when I checked it out, it said, "301 Moved Permanently". Excuse me? As it turns out, there is a 301 error section in the Subversion FAQs. It says that this typically means your [...]]]></description>
			<content:encoded><![CDATA[<p>My Linux box was hosting Subversion with no problem. I added a new repository to the several that were already present, and when I checked it out, it said, "301 Moved Permanently". Excuse me?</p>
<p>As it turns out, there is a <a href="http://subversion.tigris.org/faq.html#301-error" target="_blank">301 error</a> section in the Subversion FAQs. It says that this typically means your Apache configuration is invalid (nope, the rest of my repositories worked just fine) or your repository has the same path as a literal directory on your web root. <em>Ahhh! </em></p>
<p>Sure enough, my subversion path was http://myserver.com/xyz/, and I had a literal directory named "xyz" in the web root. I changed that directory name, and Subversion would then allow me to checkout the repository with no problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/how-to-fix-301-error-for-subversion-checkouts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upgrading Subversion Requires a Bindings Update for Trac!</title>
		<link>http://blog.crankybit.com/upgrading-subversion-requires-a-bindings-update-for-trac/</link>
		<comments>http://blog.crankybit.com/upgrading-subversion-requires-a-bindings-update-for-trac/#comments</comments>
		<pubDate>Fri, 30 Nov 2007 20:49:24 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Subversion]]></category>
		<category><![CDATA[Trac]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/upgrading-subversion-requires-a-bindings-update-for-trac/</guid>
		<description><![CDATA[My Subversion/Trac server was at Trac v0.9.6 and Subversion v1.3.x because those were the latest stable releases when I set up the server. I decided it would be relatively quick and painless to at least get the latest version of Subversion (v1.4.5) installed since I didn't see anything on the web about Trac v0.9.6 being [...]]]></description>
			<content:encoded><![CDATA[<p>My Subversion/Trac server was at Trac v0.9.6 and Subversion v1.3.x because those were the latest stable releases when I set up the server.  I decided it would be relatively quick and painless to at least get the latest version of Subversion (v1.4.5) installed since I didn't see anything on the web about Trac v0.9.6 being incompatible with newer Subversion builds.</p>
<p>Using the Windows binary installer, I had no problem installing Subversion v1.4.5 on the server. I tested everything and Subversion still worked, it showed the new version when accessing via web access, and Trac still worked fine.</p>
<p>Alas: Don't forget that an upgraded version of Subversion will not upgrade your repository. It <u>will</u> upgrade a working copy of a checked-out repository, but it will not upgrade the repository itself.</p>
<p>That said, I was unaware of one more step that you must take to upgrade Subversion on a Subversion/Trac setup: You must also upgrade the Python bindings to Subversion.</p>
<p>This became apparent the next time I created a <u>new</u> repository, which was not a v1.4.x repository, and when I tried to build a Trac environment to point to it, Trac got upset because of the classic "<a href="http://trac.edgewall.org/ticket/3943" target="_blank">Expected version '3' of repository; found version '5'</a>" error. To fix this, you must set up new bindings to the new version of Subversion, as explained in the <a href="http://trac.edgewall.org/wiki/TracSubversion" target="_blank">TracSubversion</a> page.</p>
<p>Now, I obviously love Subversion and I love Trac, but honestly, straight-forward documentation that is easy to understand for someone who doesn't want to get in the thick of it isn't really the strong suit for these communities, at least when it comes to installation and deployment on the server. What exactly it means--and how to do it--when they say, "Update the Subversion bindings" is not easy to understand. However, the solution <u>is</u> simple.  All that is needed is to <a href="http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91&amp;expandFolder=91&amp;folderID=74" target="_blank">download</a> the appropriate "svn-python" Windows installer that matches your version of Subversion and Python (in my case, 1.4.5 and py2.3) and run it on the server.</p>
<p>In my case, I had to stop Apache for the installation to succeed. Upon restarting Apache, everything worked great.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/upgrading-subversion-requires-a-bindings-update-for-trac/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Configuring Subversion for HTTP Access Behind Proxy</title>
		<link>http://blog.crankybit.com/configuring-subversion-for-http-access-behind-proxy/</link>
		<comments>http://blog.crankybit.com/configuring-subversion-for-http-access-behind-proxy/#comments</comments>
		<pubDate>Fri, 19 Jan 2007 22:23:41 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/configuring-subversion-for-http-access-behind-proxy/</guid>
		<description><![CDATA[For the life of me, I couldn't figure out why I was unable to checkout from my Subversion repository while I was at work. It worked while I was at home (where my Subversion server is) just a few days ago, and I can view the repository using Subversion's built-in web page functionality, but if [...]]]></description>
			<content:encoded><![CDATA[<p>For the life of me, I couldn't figure out why I was unable to checkout from my Subversion repository while I was at work. It worked while I was at home (where my Subversion server is) just a few days ago, and I can view the repository using Subversion's built-in web page functionality, but if I tried to access the repository from the command-line client or TortoiseSVN, I would get an error message.</p>
<blockquote><p>C:>svn  co  <a href="http://myserver/Path/To/Proj/">http://MyServer/Path/To/Proj/</a>  MyProj<br />
svn: REPORT request failed on '/Proj/!svn/vcc/default'<br />
svn: REPORT of '/Proj/!svn/vcc/default': 400 Bad Request (<a href="http://myserver/">http://MyServer</a>)</p></blockquote>
<p>Yeah, <em>that's</em> not cryptic. Fortunately, the solution is simple. Sander Striker explained in a thread <a href="http://svn.haxx.se/users/archive-2004-02/0982.shtml" target="_blank">REPORT request failed ... 400 Bad Request</a> that if you're behind a proxy at work, and the proxy isn't configured to support the necessary Subversion calls REPORT, your request will fail.</p>
<p>Like he says in his message, you could request that the proxy be configured to allow the necessary requests, but you could just as well configure your server to work on a different port. Now, I <u>like</u> the fact that my Subversion calls can work on port 80, and I don't want to change that. So, I configured Apache to have my Subversion sites work on an <em>additional </em>port.</p>
<p>In the following example, let's use port 81 as the additional port. So my example URL <a href="http://myserver/Path/To/Proj/">http://MyServer/Path/To/Proj/</a> would become <a href="http://MyServer:81/Path/To/Proj/">http://MyServer:81/Path/To/Proj/</a>.</p>
<p>At the following spots in your httpd.conf file, make the one-time additions as marked in bold italics:</p>
<blockquote><p>Listen 80<br />
<strong><em>Listen 81</em></strong></p></blockquote>
<p>And... </p>
<blockquote><p>NameVirtualHost *:80<br />
<strong><em>NameVirtualHost *:81</em></strong></p></blockquote>
<p>And for every virtual host entry you have for a Subversion site (I host a couple different Subversion sites), add <strong>*:81</strong> in the VirtualHost header:</p>
<blockquote><p>< VirtualHost *:80 <strong><em>*:81 </em></strong>></p></blockquote>
<p>After restarting Apache, you will now be able to continue to use the URLs you normally use, but anytime you need to checkout from the repository while at work behind a proxy, you can use port 81 to do so successfully.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/configuring-subversion-for-http-access-behind-proxy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Proper Placement of mod_dav_svn</title>
		<link>http://blog.crankybit.com/proper-placement-of-mod_dav_svn/</link>
		<comments>http://blog.crankybit.com/proper-placement-of-mod_dav_svn/#comments</comments>
		<pubDate>Mon, 27 Nov 2006 13:15:30 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/proper-placement-of-mod_dav_svn/</guid>
		<description><![CDATA[When installing a configuring Subversion to work through Apache, you might get an error like this when attempting to start up httpd: Cannot load /etc/httpd/modules/mod_dav_svn.so into server: /etc/httpd/modules/mod_dav_svn.so: undefined symbol: dav_xml_get_cdata Please note! Some people have indicated that this is because Apache wasn't configured with DAV support when it was compiled on your distro. The [...]]]></description>
			<content:encoded><![CDATA[<p>When installing a configuring Subversion to work through Apache, you might get an error like this when attempting to start up httpd:</p>
<blockquote><p>Cannot load /etc/httpd/modules/mod_dav_svn.so into server: /etc/httpd/modules/mod_dav_svn.so: undefined symbol: dav_xml_get_cdata</p></blockquote>
<p>Please note! Some people have indicated that this is because Apache wasn't configured with DAV support when it was compiled on your distro. The answer might be a lot simpler than that.</p>
<p>Garrett Rooney <a href="http://svn.haxx.se/users/archive-2005-12/0882.shtml" target="_blank">noted </a>that it might be as simple as just making sure that mod_dav is loaded <em>before</em> loading mod_dav_svn! I was experiencing this error, and a simple rearrangement of my LoadModule commands in httpd.conf fixed it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/proper-placement-of-mod_dav_svn/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Leave It To Apple To Bring Revision Control To The Masses</title>
		<link>http://blog.crankybit.com/leave-it-to-apple-to-bring-revision-control-to-the-masses/</link>
		<comments>http://blog.crankybit.com/leave-it-to-apple-to-bring-revision-control-to-the-masses/#comments</comments>
		<pubDate>Sat, 09 Sep 2006 07:00:58 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/leave-it-to-apple-to-bring-revision-control-to-the-masses/</guid>
		<description><![CDATA[On August 7, 2006, Apple previewed Mac OS X 10.5 Leopard at the WWDC. As usual, some new features received a lot of excitement whereas some received criticism. Time Machine, Apple's automated backup solution, received acclaim from many people because, as usual, Apple makes the process seem so easy and of course even manages to [...]]]></description>
			<content:encoded><![CDATA[<p>On August 7, 2006, Apple previewed Mac OS X 10.5 Leopard at the WWDC. As usual, some new features received a lot of excitement whereas some received criticism. <a href="http://www.apple.com/macosx/leopard/timemachine.html" target="_blank"><span style="font-weight: bold">Time Machine</span></a>, Apple's automated backup solution, received acclaim from many people because, as usual, Apple makes the process seem so easy and of course even manages to make it fun with the eye candy and intuitive interface. Some people yawned at the app, claiming that it doesn't deserve any attention because it is just a glorified backup app, which has been available in Windows for years.</p>
<p>Summing it up as a glorified backup app is an obscene oversimplification. As a developer, I immediately recognized in Time Machine the likelihood that it is running on top of a <a href="http://en.wikipedia.org/wiki/Revision_control" target="_blank">revision control</a> system, and that is what really fascinates me about it, and incidentally that is also what I feel many people misunderstand about it, leading them to discount it. I'm <a href="http://mydreamapp.com/forums/viewtopic.php?id=538" target="_blank">not alone</a> in making this connection; really, any developer who uses and understands source code repositories probably had the thought cross his or her mind. One of the major advantages mentioned in discussions about revision control is the fact that you  can always retrieve your file as it existed at any point in the past when it was committed to the repository.</p>
<p>And it's not a stretch to see Apple borrowing revision control software to implement Time Machine. Subversion is a very popular revision control project in the opensource community. Sitting on top of FreeBSD, Apple has incorporated many other opensource projects in Mac OS X. For instance, OpenGL, Apache, SSH, FTP, CUPS, and Samba come to mind, just to name a few. Why not add Subversion to the list of excellent technologies to incorporate into an excellent OS?</p>
<p>If Time Machine <span style="text-decoration: underline;">is</span> running on top of Subversion or a similar revision control system, that would address the concerns that some people have--people who might not understand how revision control systems work. Some people have expressed a concern that a backup drive would not be able to support Time Machine for very long before filling up. For instance, if you have a 1GB file (perhaps a video clip) and make a very small change to it, will Time Machine record that change by making another copy of the entire file? If Time Machine made its backups as full copies of the changed files, you can imagine how quickly a backup volume would fill up. But that simply isn't how most revision control software works. Most revision control software, including Subversion, uses <a href="http://en.wikipedia.org/wiki/Delta_compression" target="_blank">Delta Compression</a> to calculate only the <em>changes</em> made to a file, and then saves only those changes. Thus, a file can be committed to a repository a dozen times, and yet the amount of drive space taken up would only amount to the changes made, plus perhaps a very slight amount of overhead in the repository for tracking each change.</p>
<p>So that covers feasibility. With some software like Subversion, Time Machine could provide a backup of your entire volume and actually support it for a decent period of time thanks to efficient delta compression. What about the logistics of finding the changed files and saving those changes? This would be simple even with Subversion in its present state. Out of the box, Subversion provides the ability to search for files that have changed since the last "commit", or the last time changes were saved. Time Machine would just have to ask Subversion to report all the files that have changed, then run the commit. This could be scheduled to execute at a given time, say, midnight. In the event that the computer was off at the scheduled time, the steps could be executed immediately upon startup.</p>
<p>In the past, I've thought how nice it would be if all the files on my computer could go under revision control just like my source code when I'm working on an application. It would be just Apple's style to make that possible not just for tech geeks who use Subversion, but to make it possible for anyone, even the guy who doesn't care a lick about understanding revision control.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/leave-it-to-apple-to-bring-revision-control-to-the-masses/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Organizing a Source Code Repository for Web Development</title>
		<link>http://blog.crankybit.com/organizing-a-source-code-repository-for-web-development/</link>
		<comments>http://blog.crankybit.com/organizing-a-source-code-repository-for-web-development/#comments</comments>
		<pubDate>Tue, 05 Sep 2006 07:45:15 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[General Web Dev.]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/organizing-a-source-code-repository-for-web-development/</guid>
		<description><![CDATA[When you develop applications, you may use a revision control system like Subversion. If you are new at it, using revision control for web development may feel foreign at first, and understandably so; source code revision control was established before the web paradigm existed. Nevertheless, there are ways that the repository organization of traditional application development can serve our web development [...]]]></description>
			<content:encoded><![CDATA[<p>When you develop applications, you may use a revision control system like Subversion. If you are new at it, using revision control for web development may feel foreign at first, and understandably so; source code revision control was established before the web paradigm existed. Nevertheless, there are ways that the repository organization of traditional application development can serve our web development well; conversely, we can also use the repository in new ways that really benefit us on the web platform.</p>
<p align="center"><strong><u>Put Those Development Files in Version Control!</u></strong></p>
<p>To give yourself the best organization within your web application project's repository, be sure to take all aspects of your development into consideration, not just the organization of the deployable code itself. For instance, just like in compiled application development, you may have some workfiles that ought to be in the repository: Photoshop images, Flash project files, uncompressed audio or video, and similar development files. Or perhaps unit testing code, which need not be deployed on your production server.</p>
<p>There's nothing worse than realizing that you no longer have these development files when the time comes to make some requested changes. It is definitely wise to include them in your repository. So why not have a subdirectory structure under trunk separating your dev files from your web files? Perhaps something like this:</p>
<ul>
<li>trunk</li>
<ul>
<li>dev</li>
<li>www</li>
</ul>
</ul>
<p align="center"><strong><u>Keep Them Separated</u></strong> </p>
<p>Furthermore, in some cases, you may have one web application, but portions of it reside on different websites. For instance, perhaps you have a public-facing web application on your company's public website, but the administrative portion resides on your intranet site. Or perhaps the web application is just one module of a larger project whose technology reach is more broad than just the web. It would be wise to have that clearly defined in your repository structure as well.</p>
<p><strong>Multisite Example.</strong></p>
<table width="99%" border="0">
<tr>
<td>
<ul>
<li>trunk
<ul>
<li>dev</li>
<li>www</li>
<li>intranet </li>
</ul>
</li>
</ul>
</td>
<td> - or -</td>
<td>
<ul>
<li> trunk</li>
<ul>
<li>dev</li>
<li>www</li>
<ul>
<li>public</li>
<li>intranet</li>
</ul>
</ul>
</ul>
</td>
</tr>
</table>
<p><strong>Multitech Example (VB and web app combination).</strong></p>
<table width="99%" border="0">
<tr>
<td>
<ul>
<li>trunk
<ul>
<li>dev</li>
<li>www</li>
<li>vb </li>
</ul>
</li>
</ul>
</td>
<td> - or -</td>
<td>
<ul>
<li> trunk</li>
<ul>
<li>dev</li>
<li>vb</li>
<li>www</li>
<ul>
<li>public</li>
<li>intranet</li>
</ul>
</ul>
</ul>
</td>
</tr>
</table>
<p align="center"><strong><u>Clearly Mark the Live Release</u></strong> </p>
<p>One aspect of web application development that is really handy with revision control systems like Subversion is that you can also use the revision control system to help with deployment of the application. In fact, you can even use it to help keep track of which version of the app is a "live" release.</p>
<p>In order to accomplish this, you can <em>check out</em> your web application directly onto your webserver. This can be difficult if you only have FTP access to your server, although it can be done with utilities that map FTP connections to local paths on your computer. However, if you have command-line access or network access to your server, checking out files from the repository directly onto your server should be very similar to checking out files on your workstation. Please note that checking out a working copy of your repository onto your webserver is a security risk unless you supply your webserver a directive to disallow read access to the .svn directories that Subversion creates in the working copy. The <a href="http://labs.redbd.net/blog/index.cfm/2006/7/5/Website-Releases-via-Subversion-SVN" target="_blank">Website Releases via Subversion</a> article at RedBalloon Labs explains how to do this nicely.</p>
<p>So, what is the benefit of checking out a working copy onto your server? If you have a QA server you will be testing your code on, then perhaps you will check out the web application in the trunk directory. Once you've checked out the code, all you need to do is run an update against the working copy on the server to update it to the latest trunk code!</p>
<p>That's great for testing purposes, but how can we garner the same benefit for our production server? When testing is completed, you will likely tag a version of trunk in the tags directory. At this point, you <em>could</em> check out the version in the tags directory onto your production server. However, this course has a couple caveats: <strong>(a)</strong> It assumes you will always have the latest tagged release on your production server. <strong>(b)</strong> It will require a switch command to migrate the server code to the new version. If you're fine with these considerations, then by all means, check out the latest version from the tags directory and consider yourself done.</p>
<p>I, on the other hand, am not comfortable with those conditions. If your company has any sort of delay between the moment technical work has been completed and when it can actually be deployed, then a tagged version may not be the version on your production server, even though it is the latest and greatest tagged code. Certain versions may never even see <u>any</u> time on the production server if they are bug fix releases that are held back until perhaps more bug fixes are made and a later version is deployed as a cumulative release. Furthermore, if someone else needed to redeploy the application, they should be able to know what version to redeploy.</p>
<p>The solution to these problems is to create a copy/branch of the tagged version as a copy called "live" or something similar. You could keep the "live" copy in the tags directory, but I found it more straightforward to keep it at the repository's root level. This will mean your repository's root might look like this:</p>
<ul>
<li>trunk</li>
<li>branches</li>
<li>tags</li>
<li><em>live</em></li>
</ul>
<p>Live being, not an actual directory, but simply a copy of a version in the tags directory, which is actually a copy of trunk at a particular revision! By following this approach, it will always be clear to anyone how to deploy your website or web application onto the production server. All they have to do is check out the live directory at the root of your repository.</p>
<p>Furthermore, updating is a breeze on the server end. Once you are set to change live to a new version, simply delete live and make a copy of the new version. Then, on the server, all that needs to be done is to run an update on the working copy, and all of your changes will fall into place. I love this part of the process. It feels so clean and inobtrusive, which is naturally important for a production deployment upgrade.</p>
<p align="center"><strong><u>Repository Structure Overview</u></strong></p>
<p>If we were to employ all of these tips, our repository might look something like this:</p>
<ul>
<li>trunk</li>
<ul>
<li>dev</li>
<li>www</li>
<ul>
<li>public</li>
<li>intranet</li>
</ul>
</ul>
<li>branches </li>
<li>tags</li>
<ul>
<li><em>v1.0</em> <span style="font-size: 0.6em">(Copy of a revision of trunk)</span></li>
<li><em>v1.0.1</em> <span style="font-size: 0.6em">(Copy of a revision of trunk)</span></li>
</ul>
<li><em>live</em> <span style="font-size: 0.6em">(Copy of a version in tags)</span></li>
</ul>
<p>For many of us, simply taking the step of using a revision control system is a great acomplishment alone. If you're ready to begin leveraging revision control for web development even further, then the tips we just covered might be helpful to you. I invite you to share with me any standards or practices that you are employing in revision control that I haven't covered here. I'd love to learn about them.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/organizing-a-source-code-repository-for-web-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

