<?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; Open Source</title>
	<atom:link href="http://blog.crankybit.com/tags/open-source/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>Avoiding the Password Prompt for SSH</title>
		<link>http://blog.crankybit.com/avoiding-the-password-prompt-for-ssh/</link>
		<comments>http://blog.crankybit.com/avoiding-the-password-prompt-for-ssh/#comments</comments>
		<pubDate>Wed, 15 Oct 2008 16:22:11 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[howto]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/?p=311</guid>
		<description><![CDATA[It's handy to establish an SSH key between machines so that SSH-related commands don't prompt you for a password. This is handy to quickly SSH into another machine, and it's even more handy when setting up SSH commands in automated scripts. For instance, you may want to execute some rsync statements in a script that [...]]]></description>
			<content:encoded><![CDATA[<p>It's handy to establish an SSH key between machines so that SSH-related commands don't prompt you for a password. This is handy to quickly SSH into another machine, and it's even more handy when setting up SSH commands in automated scripts. For instance, you may want to execute some rsync statements in a script that runs on a regular basis. It's better to have an established SSH key between the two machines than to have a password embedded in the script.</p>
<p>I recently reinstalled the OS on one of my Macs, and I've got backup scripts on my CentOS Linux box that use rsync to back up some pertinent data, so I had to reestablish the SSH key between the machines and had a hard time remembering how to do it. So this time I'm documenting what I had to re-learn.</p>
<p>First of all, there's a <a href="http://nixcraft.com/1196-post2.html" target="_blank">great post over at nixCraft</a> that basically explains how to do it. But allow me to explain more thoroughly, ahem, dumbed down to my level. </p>
<p>The key is remembering which machine is filling which role when you're reading the instructions. I'll call them the "Acting" machine--the one who is taking action and performing a command, let's say an rsync command--and the "Target" machine--the one who is being acted upon. In my case, the Linux server is the acting machine performing the rsync command, and my Mac is the target.</p>
<p>The process is simple. On the "Target" machine, generate a key, and then give that key to the "Acting" machine, which effectively gives it "permission" to login without the need to supply username/password credentials.</p>
<p>So, from the "Target" machine, in this case, my Mac, type the following command:</p>
<p>ssh-keygen -t rsa</p>
<p>This will generate a couple files that serve as a key for accessing the Mac. The ssh-keygen command may ask you where to store the key and what password to use. Just hit enter to use the default path and a blank password.</p>
<p>Next, still from the "Target" machine (my Mac), type:</p>
<p>ssh <em>MyUsername@ActingServer</em> "mkdir .ssh"<br />
scp .ssh/id_rsa.pub <em>MyUsername@ActingServer</em>:.ssh/authorized_keys2</p>
<p>In the code above, <em>MyUsername@ActingServer</em> would be the username and address (for instance, perhaps the IP address) of the "Acting" machine, in my case, the Linux server. In the first line, you're just creating the .ssh directory if it doesn't exist. In the second line, you're copying the key you generated from the "Target" machine to the "Acting" machine, or from the Mac to the Linux server.  Note that the scp command will ask for the password to the <em>MyUsername</em> account because it is connecting to that server to send it the key.</p>
<p>Voile. As if by magic, the "Acting" machine should now be able to SSH into the "Target" machine without a password prompt. Correspondingly, you should be able to perform rsync and other SSH commands without a password prompt. Please note, however, that <em>this is only a one-way key.</em><em> </em>We only gave my Linux server permission to access my Mac.</p>
<p><strong>What if I want my Mac to similarly login to the server without a password prompt?</strong> In that case, the Mac and the server have effectively switched roles; the Mac is now the "Acting" machine and the server is the "Target" machine, so we just have to repeat the process from the other direction. Generate a key from the server and send it to the Mac. At that point, both machines will be able to access each other without a password prompt. </p>
<p><strong>What if I have multiple "Targets" that the "Acting" machine will connect to?</strong> For instance, perhaps I have multiple Macs, and the Linux server is running scripts on all of them. When you're sending the key to the "Acting" server with the scp command, use a different name for each key file, don't overwrite the same file each time! So in the example code above, we're sending the key as "authorized_keys2". When repeating this process for multiple targets, send the keys as "authorized_keys3", and so forth.</p>
<p>Hopefully this will clear up some confusion regarding this process.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/avoiding-the-password-prompt-for-ssh/feed/</wfw:commentRss>
		<slash:comments>8</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>Ubuntu v7.10 on Parallels</title>
		<link>http://blog.crankybit.com/ubuntu-v710-on-parallels/</link>
		<comments>http://blog.crankybit.com/ubuntu-v710-on-parallels/#comments</comments>
		<pubDate>Sun, 11 Nov 2007 21:28:24 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Virtualization]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/ubuntu-v710-on-parallels/</guid>
		<description><![CDATA[You'll get display server issues if you try to install Ubuntu v7.10 in Parallels. But the Parallels Tools CD does have drivers to fix those problems. This blog post, Ubuntu 7.10 Install Guide, helps you get past the display server issues long enough to get the OS installed, and then gives instructions on how to [...]]]></description>
			<content:encoded><![CDATA[<p>You'll get display server issues if you try to install Ubuntu v7.10 in Parallels. But the Parallels Tools CD does have drivers to fix those problems. This blog post, <a href="http://infosonic.wordpress.com/2007/10/21/ubuntu-710-install-guide-parallels-macbook-pro/">Ubuntu 7.10 Install Guide</a>, helps you get past the display server issues long enough to get the OS installed, and then gives instructions on how to get the Parallels Tools installed. </p>
<p>It worked great. Instructions were very clear and the process was mildly simple.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/ubuntu-v710-on-parallels/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Windows Vista and Samba Not Getting Along: NTLMv2 is the Culprit</title>
		<link>http://blog.crankybit.com/vista-samba-ntlmv2/</link>
		<comments>http://blog.crankybit.com/vista-samba-ntlmv2/#comments</comments>
		<pubDate>Sat, 03 Nov 2007 05:04:33 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/vista-samba-ntlmv2/</guid>
		<description><![CDATA[After installing Windows Vista, I could not connect to my Samba fileshares. I'm running Samba v3.0.10 on CentOS v4.4. It turns out that NTLMv2, the authentication protocol, is required by default on Windows Vista. According to the Samba Features by Release wiki page, support for NTLMv2 in Samba wasn't fully developed until Samba v3.0.21. Running yum [...]]]></description>
			<content:encoded><![CDATA[<p>After installing Windows Vista, I could not connect to my Samba fileshares. I'm running Samba v3.0.10 on CentOS v4.4.</p>
<p>It turns out that <a target="_blank" href="http://en.wikipedia.org/wiki/NTLM#NTLMv2">NTLMv2</a>, the authentication protocol, is <em>required</em> by default on Windows Vista. According to the <a target="_blank" href="http://wiki.samba.org/index.php?title=Samba_Features_added/changed_%28by_release%29&amp;redirect=no#3.0.21.7Ba.2Cb.2Cc.7D">Samba Features by Release</a> wiki page, support for NTLMv2 in Samba wasn't fully developed until Samba v3.0.21.</p>
<p>Running yum would be a quick way to upgrade Samba to a more recent release. For some reason, though, the repositories I'm pointing to only have v3.0.10 as the latest available update. Rather than hassling with it, I found an article that attacks the issue from the Vista end.</p>
<p>The article <a target="_blank" href="http://www.builderau.com.au/blogs/codemonkeybusiness/viewblogpost.htm?p=339270746">Get Vista and Samba to Work</a> explains how to get Vista to use the older authentication protocols, like the original NTLM. After making this change, I was able to login to my shares immediately.</p>
<p>Basically, all you need to do is run the Local Security Policies console snapin (secpol.msc), open Local Policies --&gt; Security Options --&gt; Network Security: LAN Manager authentication level, and change the setting from "NTLMv2 responses only" to one of the more lenient settings, like "LM and NTLM – use NTLMV2 session security if negotiated".</p>
<p>This works for me because I have one, sometimes two, machines with Windows Vista connecting to my server. If you had lots of machines connecting to the server, it'd obviously be worth your time to just upgrade Samba to a version that supports NTLMv2.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/vista-samba-ntlmv2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Simple Backup and Restore With Tar</title>
		<link>http://blog.crankybit.com/simple-backup-and-restore-with-tar/</link>
		<comments>http://blog.crankybit.com/simple-backup-and-restore-with-tar/#comments</comments>
		<pubDate>Fri, 27 Jul 2007 14:03:51 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/simple-backup-and-restore-with-tar/</guid>
		<description><![CDATA[I've got a Linux server that acts as a fileserver, among other things. I have hundreds of gigabytes of data on it, accessible to any of my computers but in a simplified fashion because I'm not duplicating the data on each computer, plus backup is more straightforward because I just need to backup the server. [...]]]></description>
			<content:encoded><![CDATA[<p>I've got a Linux server that acts as a fileserver, among other things. I have hundreds of gigabytes of data on it, accessible to any of my computers but in a simplified fashion because I'm not duplicating the data on each computer, plus backup is more straightforward because I just need to backup the server. And Linux is great for automation, and for raw processing of files in bulk. <img src='http://blog.crankybit.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><strong>So, how to back up the data?</strong></p>
<p>I have installed <a href="http://www.webmin.com/" target="_blank">Webmin</a>, which makes backing up directories in the filesystem trivial. With a web form, you can specify everything about your backup: What directories to backup, where to save the backup file, whether you want to just tar it or also bzip the archive; it even handles scheduling it as a cron job, notifying you the results via email, and more.</p>
<p>If you were do to this manually, though, your tar command might look something like this:</p>
<div class="igBar"><span id="ldos-12"><a href="#" onclick="javascript:showCodeTxt('dos-12'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">DOS:</span>
<div id="dos-12">
<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;">tar -c -f /path/of/archive.tar.bz2 --bzip /path/to/backup </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>You're telling tar, "Please <strong>-c</strong>reate a <strong>-f</strong>ile at /path/of/archive.tar.bz2, and along the way, compress it using <strong>--bzip</strong>. The path to archive is /path/to/backup."</p>
<p>I was backing up a 15GB directory and didn't want to make the server spend the extra time compressing all that data, so to save time I did not use the --bzip argument, and so instead it just creates a tar file which I'd name archive.tar.</p>
<p>Great. We're backing up on a regular basis now. I feel much better.</p>
<p><strong>Oh no, I need to retrieve a single file from my backup! How do I do it?</strong></p>
<p>It would be overkill to extract the <em>whole</em> archive, especially when it's really big like my example, when all you need is a single file, perhaps just a few megabytes in size.</p>
<p>Well, if you <em>were</em> to extract the whole archive, you might type:</p>
<div class="igBar"><span id="ldos-13"><a href="#" onclick="javascript:showCodeTxt('dos-13'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">DOS:</span>
<div id="dos-13">
<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;">tar -xvf archive.tar </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>You're telling tar to e<strong>x</strong>tract from the <strong>f</strong>ile archive.tar, and be <strong>v</strong>erbose, showing all the files you extract.</p>
<p>Again, that's a waste of time and hard drive space. Instead, --list the archive to find the file you need, and then --extract the exact file by specifying it to tar.</p>
<p>You could just list all the files and try to find your file in the list:</p>
<div class="igBar"><span id="ldos-14"><a href="#" onclick="javascript:showCodeTxt('dos-14'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">DOS:</span>
<div id="dos-14">
<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;">tar --list -f archive.tar </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Again, a waste of time. Make Linux do the work. I know the file I need to restore is foobar.txt, so tell Linux to return just that file by piping the archive list into grep:</p>
<div class="igBar"><span id="ldos-15"><a href="#" onclick="javascript:showCodeTxt('dos-15'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">DOS:</span>
<div id="dos-15">
<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;">tar --list -f archive.tar | grep foobar.txt </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>It crunches through the archive, looking for that file. Finally, it returns, say, "my/path/to/foobar.txt". Excellent! Now ask tar to extract just that single file from the archive:</p>
<div class="igBar"><span id="ldos-16"><a href="#" onclick="javascript:showCodeTxt('dos-16'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">DOS:</span>
<div id="dos-16">
<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;">tar -x -f archive.tar my/path/to/foobar.txt </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Now, tar will wade through all the files in the archive, and only extract the single file.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/simple-backup-and-restore-with-tar/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Remotely Start a VMware Server</title>
		<link>http://blog.crankybit.com/remotely-start-a-vmware-server/</link>
		<comments>http://blog.crankybit.com/remotely-start-a-vmware-server/#comments</comments>
		<pubDate>Mon, 07 May 2007 02:07:52 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Virtualization]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/remotely-start-a-vmware-server/</guid>
		<description><![CDATA[There have been a few times now that I needed to start a VMware virtual machine on my server but I wasn't on a PC that had the VMware console installed. Besides, unless I'm on my own network, starting up a server with the VMware console can be a pain due to slower upstream speeds. [...]]]></description>
			<content:encoded><![CDATA[<p>There have been a few times now that I needed to start a VMware virtual machine on my server but I wasn't on a PC that had the VMware console installed. Besides, unless I'm on my own network, starting up a server with the VMware console can be a pain due to slower upstream speeds.</p>
<p>Well, I finally took the time to find out how to do this from the command line. It's simple. </p>
<p>Get the current state of the virtual machine. Is it running or not?</p>
<div class="igBar"><span id="lcode-19"><a href="#" onclick="javascript:showCodeTxt('code-19'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-19">
<div class="code">
<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;">$ vmware-cmd /path/to/vm/machine.<span style="">vmx</span> getstate </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>And start it.</p>
<div class="igBar"><span id="lcode-20"><a href="#" onclick="javascript:showCodeTxt('code-20'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-20">
<div class="code">
<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;">$ vmware-cmd /path/to/vm/machine.<span style="">vmx</span> start </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>There are many other things you can do as well. Just <span class="mono">man vmware-cmd</span>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/remotely-start-a-vmware-server/feed/</wfw:commentRss>
		<slash:comments>1</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>BlueDragon Works on Fedora Core 4</title>
		<link>http://blog.crankybit.com/bluedragon-works-on-fedora-core-4/</link>
		<comments>http://blog.crankybit.com/bluedragon-works-on-fedora-core-4/#comments</comments>
		<pubDate>Sat, 18 Nov 2006 07:12:17 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/bluedragon-works-on-fedora-core-4/</guid>
		<description><![CDATA[New Atlanta supports only Fedora Core 1, 2, and 3. This is sad, since Fedora Core 6 came out recently. BlueDragon 6.2 and 7 beta don't appear to work on Fedora Core 5 and 6, but just because they come with Apache 2.2. The installer script crashes initially, but with this Installer Setting Hack, the [...]]]></description>
			<content:encoded><![CDATA[<p>New Atlanta supports only Fedora Core 1, 2, and 3. This is sad, since Fedora Core 6 came out recently.</p>
<p>BlueDragon 6.2 and 7 beta don't appear to work on Fedora Core 5 and 6, but just because they come with Apache 2.2. The installer script crashes initially, but with this <a target="_blank" href="http://www.newatlanta.com/c/products/bluedragon/self_help/archiveSearch/detail?messageId=183376">Installer Setting Hack</a>, the installer will be able to install BlueDragon. That's fine and good, but once it runs, the mod_servletexec.so and mod_servletexec2.so files freak out when you actually try to start up HTTPD with BlueDragon. This appears to be caused by an updated version of the APR package (Apache Portable Runtime library). It's pretty much a roadblock to installing BlueDragon on FC5 or FC6 unless you manually install Apache 2.0.</p>
<p>All of that said, Fedora Core 4 is the most modern version of this flavor of Linux that can run BlueDragon easily. But there is one serious problem with BlueDragon on FC4.</p>
<p>Some issue with Java 1.4.2 on FC4 causes it to want to look to IPv6 sockets instead of IPv4 sockets, which causes problems, like errors that say something like this:</p>
<blockquote><p>java.net.SocketException: Invalid argument or cannot assign requested address</p></blockquote>
<p>This problem is broader than just BlueDragon, but BlueDragon is how I found out about it. Because of this problem, BlueDragon has trouble stopping its service and possibly trouble starting sometimes.</p>
<p>I learned about this problem on <a target="_blank" href="http://www.linuxquestions.org/questions/showthread.php?t=334291">this forum thread</a>, which led me to a blog post called <a target="_blank" href="http://www.jroller.com/page/dissonance/20050630#fedora_core_4_and_jdk">Fedora Core 4 and JDK 1.4.2 Problems</a>, where a fix is described that basically tells Java to prefer the IPv4 stack over the IPv6 one by including <strong>-Djava.net.preferIPv4Stack=true</strong> as a parameter in your Java call to your app.</p>
<p>To apply this to BlueDragon, we have to modify the StartBlueDragon.sh and StopBlueDragon.sh scripts, which are used for starting and stopping the service. They are located under ~/<em>BlueDragonInstallation</em>/bin/.</p>
<p>In StartBlueDragon.sh, modify this line (addition in bold) near the bottom of the file:</p>
<blockquote><p>"$JAVA_HOME/bin/java" -server <strong>-Djava.net.preferIPv4Stack=true</strong> $HEAPSIZES $OPTIONS -classpath "$NEW_CLASSPATH" com.newatlanta.webserver.BlueDragon &#038;</p></blockquote>
<p>In StopBlueDragon.sh, modify this line (addition in bold) near the bottom of the file:</p>
<blockquote><p>"$JAVA_HOME/bin/java" -server <strong>-Djava.net.preferIPv4Stack=true</strong> -classpath "$NEW_CLASSPATH" StopServletExec -host 127.0.0.1:8080</p></blockquote>
<p>After saving these files, you should now be able to successfully stop or restart the BlueDragon_Server service.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/bluedragon-works-on-fedora-core-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding a Drive to Your Linux System</title>
		<link>http://blog.crankybit.com/adding-a-drive-to-your-linux-system/</link>
		<comments>http://blog.crankybit.com/adding-a-drive-to-your-linux-system/#comments</comments>
		<pubDate>Sat, 18 Nov 2006 04:00:35 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/adding-a-drive-to-your-linux-system/</guid>
		<description><![CDATA[I have a server that has 2 IDE channels, no spare IDE cards, and 4 hard drives that I want to be running. This will obviously take up all 4 drive spaces in my 2 IDE channels. But to install the OS, I will need to use one of those spaces for the CD-ROM drive, [...]]]></description>
			<content:encoded><![CDATA[<p>I have a server that has 2 IDE channels, no spare IDE cards, and 4 hard drives that I want to be running. This will obviously take up all 4 drive spaces in my 2 IDE channels. But to install the OS, I will need to use one of those spaces for the CD-ROM drive, meaning I can only install the OS with 3 of the drives.</p>
<p>To put the fourth drive in there, I would remove the CD-ROM drive after installation of the OS and put in the fourth hard drive. So how do I configure Linux to recognize the fourth and final drive? On my Fedora Core system, it's easy. These steps will assume the drive is already partitioned and formatted. </p>
<p><strong>The mount point. </strong>First, make the directory for the mount point. For instance, I'll create a directory in the /mnt directory:</p>
<blockquote><p>mkdir /mnt/mynewdrive</p></blockquote>
<p><strong>The fstab entry. </strong>You'll have to know which letter your drive has been assigned, and the partition number of your volume. Likely, it will be hdd, since hda, hdb, and hdc will be assigned to the first three. And if the drive is just one large partition, it will obviously be partition 1. So, the desired volume in this instance would be hdd1. Thus, you can map /dev/hdd1 to the /mnt/mynewdrive directory by editing /etc/fstab with the following line:</p>
<blockquote><p>/dev/hdd1   /mnt/mynewdrive   ext3   defaults   1 1</p></blockquote>
<p>Naturally, substitute <em>ext3</em> with whatever filesystem you're using, if different.</p>
<p>You could avoid using an editor to make this change by doing a command like this:</p>
<blockquote><p>echo /dev/hdd1   /mnt/mynewdrive   ext3   defaults   1 1 >> /etc/fstab</p></blockquote>
<p><strong>First-time mount. </strong>Then, simply call a mount command:</p>
<blockquote><p>mount /mnt/mynewdrive</p></blockquote>
<p>You'll only have to do this the first time. If you have automounting set up, the drive will automount in the future.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/adding-a-drive-to-your-linux-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating Linux Password Files</title>
		<link>http://blog.crankybit.com/creating-linux-password-files/</link>
		<comments>http://blog.crankybit.com/creating-linux-password-files/#comments</comments>
		<pubDate>Thu, 16 Nov 2006 05:46:19 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/creating-linux-password-files/</guid>
		<description><![CDATA[This is primarily a reminder for myself. If you're not authenticating against a database or network directory store, your web app may need to just authenticate against a standard Linux password file. Creating one is easy: htpasswd -c [filename] [username] After prompting you for the desired password for this user, it will create the file [...]]]></description>
			<content:encoded><![CDATA[<p>This is primarily a reminder for myself. If you're not authenticating against a database or network directory store, your web app may need to just authenticate against a standard Linux password file.</p>
<p>Creating one is easy:</p>
<blockquote><p>htpasswd -c <em>[filename] [username]</em></p></blockquote>
<p>After prompting you for the desired password for this user, it will create the file (or wipe it out if it exists), and insert the user with the password, naturally encrypted.</p>
<p>Go without the -c parameter to add additional users to an existing password file. Finally, use a -d parameter to delete a certain user from a password file.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/creating-linux-password-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sudo Comic</title>
		<link>http://blog.crankybit.com/sudo-comic/</link>
		<comments>http://blog.crankybit.com/sudo-comic/#comments</comments>
		<pubDate>Wed, 27 Sep 2006 12:41:02 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Funny]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/sudo-comic/</guid>
		<description><![CDATA[Jenny sent me a link to this great comic: See it over at xkcd: sandwich!]]></description>
			<content:encoded><![CDATA[<p>Jenny sent me a link to this great comic:</p>
<p><img src="http://imgs.xkcd.com/comics/sandwich.png" /></p>
<p>See it over at <a href="http://xkcd.com/c149.html" target="_blank">xkcd: sandwich</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/sudo-comic/feed/</wfw:commentRss>
		<slash:comments>0</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>The Mysterious Vanishing WordPress Posts</title>
		<link>http://blog.crankybit.com/the-mysterious-vanishing-wordpress-posts/</link>
		<comments>http://blog.crankybit.com/the-mysterious-vanishing-wordpress-posts/#comments</comments>
		<pubDate>Fri, 08 Sep 2006 03:16:58 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Site Configuration]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/the-mysterious-vanishing-wordpress-posts/</guid>
		<description><![CDATA[Three of my recent posts from August 2006 have been mysteriously cut off at the knees (two articles about SELinux and one article about Apple releasing the Mac Pro). The first opening sentences remained, but then mid-sentence at a variant length, the article body was truncated. One of the posts was particularly lengthy, and naturally [...]]]></description>
			<content:encoded><![CDATA[<p>Three of my recent posts from August 2006 have been mysteriously cut off at the knees (two articles about SELinux and one article about Apple releasing the Mac Pro).  The first opening sentences remained, but then mid-sentence at a variant length, the article body was truncated. One of the posts was particularly lengthy, and naturally I didn't have a backup of the article in any fashion. That is extremely disappointing.</p>
<p>To prevent the lamentable agony of this kind of loss, I could: <strong>(a)</strong> Set up a WordPress scheduled task (with plugins that provide such functionality) to backup the database on a regular basis, or <strong>(b) </strong>I could backup the database manually after I post an article. As a different approach, and the most fun because it involves programming, <strong>(c) </strong>I could set up a scheduled task on my server at home to pull the RSS feed from my site on a daily basis and save that.</p>
<p>My server at home is a Linux box (currently Fedora Core 4), so a quick little Linux script is the best way to go. This is exceptionally easy, so let's take a look:</p>
<blockquote><p>fn=/backuppath/rss/nazin-`date --iso-8601=date`.xml<br />
url=http://blog.nazin.com/index.php/feed/<br />
curl -o $fn $url</p></blockquote>
<p>This obviously could be a one-liner, but to dumb it down, I put the backup file path and the URL of the RSS feed in script variables. The first line says, "Make the path inside the rss directory (relative to the location the script is ran from), with a file called 'nazin-yyyy-mm-dd.rss', using today's date." If you are new to Linux scripting, anything wrapped in ` symbols will be processed and replaced with its output. So "nazin-`date --iso-8601=date`.rss" will actually become "nazin-2006-09-07.rss" if that is today's date. The second line obviously just assigns the value of the url variable. The third line is then a basic curl call. It says, "Go browse the $url and put the output in the file at $fn."</p>
<p>I then just set up that script to run as a scheduled Cron job, and we're in business! A quick note about the path: You can leave it as a relative path, and the script will work fine when you execute it at a shell prompt, but it may fail as a Cron job. To be safe, provide an absolute path so that it works at both places.<br />
Don't leave backups to humans. We're too unreliable. Leave it to your server to handle. <img src='http://blog.crankybit.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/the-mysterious-vanishing-wordpress-posts/feed/</wfw:commentRss>
		<slash:comments>0</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>
		<item>
		<title>Making a System Image of a Windows Install</title>
		<link>http://blog.crankybit.com/making-a-system-image-of-a-windows-install/</link>
		<comments>http://blog.crankybit.com/making-a-system-image-of-a-windows-install/#comments</comments>
		<pubDate>Fri, 25 Mar 2005 21:41:00 +0000</pubDate>
		<dc:creator>Josh</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.crankybit.com/making-a-system-image-of-a-windows-install/</guid>
		<description><![CDATA[I can't count how many times I've reinstalled Windows on my workstation at home. Sometimes it's because of my obsessive need to keep a clean system; other times it's because I've hosed my system with my multiple-system boot setup. Regardless, I've been wasting my time. I could have been imaging my computer this whole time. [...]]]></description>
			<content:encoded><![CDATA[<p>I can't count how many times I've reinstalled Windows on my workstation at home. Sometimes it's because of my obsessive need to keep a clean system; other times it's because I've hosed my system with my multiple-system boot setup. Regardless, I've been wasting my time. I could have been imaging my computer this whole time.</p>
<p>So now I've wised up. Just today I made a "perfect" Windows install, with SP2, my anti-virus software, my preferred settings, and a couple of my most commonly used programs. Now that that's done, I use a Linux Live CD--which for the uninitiated, is a Linux bootable CD--and now I'm imaging my Windows partition with Linux.</p>
<p>How, you might ask? It's simple!</p>
<p>Once Linux boots up, I first login to my fileserver, which is coincidentally a Linux system as well, but it doesn't have to be. In fact, I'm actually connecting to it using Samba. Then, I simply use the DD command:</p>
<p>dd if=<em>[The partition you want to image]</em> of=<em>[The location of the file to save]</em></p>
<p>So, in my exact case, I mounted the fileshare at /ramdisk/bkup, and my partition was /dev/hda1, so:</p>
<p>dd if=/dev/hda1 of=/ramdisk/bkup/WinXPSP2.img</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.crankybit.com/making-a-system-image-of-a-windows-install/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

