<?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>BigSmoke &#187; Subversion</title>
	<atom:link href="http://blog.bigsmoke.us/tag/subversion/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.bigsmoke.us</link>
	<description>Smokes your problems, coughs fresh air.</description>
	<lastBuildDate>Sat, 04 Feb 2012 18:03:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>First steps with Subversion&#8217;s new merge tracking</title>
		<link>http://blog.bigsmoke.us/2010/01/30/svn-merge-tracking</link>
		<comments>http://blog.bigsmoke.us/2010/01/30/svn-merge-tracking#comments</comments>
		<pubDate>Sat, 30 Jan 2010 00:47:18 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=1070</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>A while ago we succeeded in upgrading the Debian server where I keep many of my SVN repositories. (The server was running on “testing”, but we hadn&#8217;t dared to upgrade it for a long time until it came time to make it “stable” again with Lenny.) On of the upgraded packages in Lenny is Subversion, now at 1.5.1, which means that I can finally start using subversions new merge tracking features.</p>

<p>To be able to use merge tracking for my existing repositories, I first have to upgrade these. From the <a href="http://subversion.tigris.org/svn_1.5_releasenotes.html#repos-upgrades">svn 1.5 release notes</a>:</p>

<blockquote>
<p>The Subversion 1.5 server works with 1.4 and older repositories, and it will not upgrade such repositories to 1.5 unless specifically requested to via the <strong><tt>svnadmin&nbsp;upgrade</tt></strong> command. This means that some of the new 1.5 features will not become available simply by upgrading your server: you will also have to upgrade your repositories. (We decided not to auto-upgrade repositories because we didn&#8217;t want 1.5 to silently make repositories unusable by 1.4 — that step should be a conscious decision on the part of the repository admin.)</p>
</blockquote>

<p>The only other machine I&#8217;m using these repos from is my <a href="/tag/t61">laptop</a>, which, running Gentoo, is already at Subversion 1.6.2. So, how do I upgrade?</p>

<p>First, I made a backup of all our SVN repos using a script that <a href="/author/halfgaar">Halfgaar</a> made to run from cron. After running that script, I initialized the upgrade procedure:</p>

<pre class="bash"><span style="color: #000066;">cd</span> /var/svn
svnadmin upgrade blog.bigsmoke.us
svn-populate-node-origins-index blog.bigsmoke.us</pre>

<p>The last command is unimportant, but may speed up the next few operations. The <a href="http://subversion.tigris.org/svn_1.5_releasenotes.html#repos-upgrades">release notes</a> again:</p>

<blockquote><p>After running <strong><tt>svnadmin&nbsp;upgrade</tt></strong>,
you may wish to also run the <a href="http://svn.collab.net/repos/svn/trunk/tools/server-side/svn-populate-node-origins-index.c">svn-populate-node-origins-index</a> program on the repository.
Subversion 1.5 maintains a node-origins index for each repository, and
builds the index lazily as the information is needed.  But for old
repositories with lots of revisions, it&#8217;s better to create the index
in one step, using the aforementioned tool, than to have live queries
be slower until the index has built itself.  See <a href="http://subversion.tigris.org/issues/show_bug.cgi?id=3024">issue
#3024</a> for details.</p></blockquote>

<p>With my data safe and the repo upgraded, it&#8217;s time to actually test the new merge tracking features:</p>

<pre class="bash"><span style="color: #000066;">cd</span> ~/blog.bigsmoke.us <span style="color: #808080; font-style: italic;"># Enter working copy (on the same server)</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># I'm now in the lichtgekruid branch.</span>
svn switch file:///var/svn/blog.bigsmoke.us/trunk
svn add wp-content/plugins/openid
svn ci -m <span style="color: #ff0000;">&quot;I was convinced this was a change which didn't belong to my feature branch&quot;</span> wp-content/plugins/openid
&nbsp;
svn switch file:///var/svn/blog.bigsmoke.us/branches/lichtgekruid
svn merge file:///var/svn/blog.bigsmoke.us/trunk
<span style="color: #808080; font-style: italic;"># The last command was a real kicker, not having to find and specify the correct range of revision numbers.</span>
&nbsp;
svn ci -m <span style="color: #ff0000;">&quot;Merged changes from trunk to 'lichtgekruid' branch.&quot;</span>
svn switch file:///var/svn/blog.bigsmoke.us/trunk
svn merge file:///var/svn/blog.bigsmoke.us/branches/lichtgekruid
<span style="color: #808080; font-style: italic;"># (Another spontaneous orgasm.)</span>
&nbsp;
svn ci -m <span style="color: #ff0000;">&quot;Merged 'lichtgekruid' branch back into trunk.&quot;</span></pre>

<p>Ok, I know I could have simply changed all these projects to use Git, and I like Git. I <em>love</em> its simplicity and flexibility. But, call me old-fashioned; I have an SVN fetish, and so far I find its merge tracking quite convincing.</p>

<p>Besides all the gotchas and pointers in the <a href="http://subversion.apache.org/docs/release-notes/1.5.html#merge-tracking">1.5 release notes</a>, there&#8217;s a lot more info about <a href="
http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword">merge tracking</a> in the <a href="http://svnbook.red-bean.com/">SVN redbook</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2010/01/30/svn-merge-tracking/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Replacing the full contents of a Subversion working (sub)dir</title>
		<link>http://blog.bigsmoke.us/2010/01/14/svn-replace-dir</link>
		<comments>http://blog.bigsmoke.us/2010/01/14/svn-replace-dir#comments</comments>
		<pubDate>Wed, 13 Jan 2010 22:01:14 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[diff]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[svn-replace-dir]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=1000</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>The annoyances that I suffered earlier today during the <a href="http://blog.bigsmoke.us/2008/03/13/upgrading-web-apps-with-diff-and-patch#comment-90523">upgrade of a WordPress plugin</a> made me turn to my <a href="http://blog.bigsmoke.us/tag/vim">favorite text-editor</a> to create a simple script, <tt><a href="http://gist.github.com/276574">svn-replace-dir</a></tt>:</p>

<pre class="bash"><span style="color: #808080; font-style: italic;">#!/bin/bash</span>
&nbsp;
usage<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    cat &lt;&lt;<span style="color: #ff0000;">&quot;EOF&quot;</span>
$<span style="color: #cc66cc;">0</span> <span style="color: #66cc66;">&#91;</span>--dry-run<span style="color: #66cc66;">&#93;</span> &lt;svn_dir&gt; &lt;replacement_dir&gt;
&nbsp;
This script replaces the contents of &lt;svn_dir&gt; with the contents of &lt;replacement_dir&gt;,
where &lt;replacement_dir&gt; is not an svn directory.
&nbsp;
Copyleft <span style="color: #cc66cc;">2010</span>, Rowan Rodrik van der Molen &lt;rowan@bigsmoke.us&gt;
EOF
<span style="color: #66cc66;">&#125;</span>
&nbsp;
fatal_error<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #0000ff;">message=</span>$<span style="color: #cc66cc;">1</span>
&nbsp;
    <span style="color: #000066;">echo</span> -e <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\e</span>[1;31m$message<span style="color: #000099; font-weight: bold;">\e</span>[0m&quot;</span>
    <span style="color: #000066;">exit</span> <span style="color: #cc66cc;">1</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
usage_error<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #0000ff;">error=</span><span style="color: #ff0000;">&quot;Wrong usage.&quot;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> -n <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
        <span style="color: #0000ff;">error=</span>$<span style="color: #cc66cc;">1</span>
    <span style="color: #b1b100;">fi</span>
&nbsp;
    <span style="color: #000066;">echo</span> -e <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\e</span>[1;31m$error<span style="color: #000099; font-weight: bold;">\e</span>[0m&quot;</span>
    <span style="color: #000066;">exit</span> <span style="color: #cc66cc;">1</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
run_command<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #000066;">echo</span> -e <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\e</span>[1;34m$1<span style="color: #000099; font-weight: bold;">\e</span>[0m&quot;</span>
&nbsp;
    <span style="color: #66cc66;">&#91;</span> <span style="color: #0000ff;">$dry_run</span> == <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#93;</span> || <span style="color: #000066;">eval</span> $<span style="color: #cc66cc;">1</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">dry_run=</span><span style="color: #cc66cc;">0</span>
<span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> $<span style="color: #cc66cc;">1</span> == <span style="color: #ff0000;">'--dry-run'</span> <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
  <span style="color: #0000ff;">dry_run=</span><span style="color: #cc66cc;">1</span>
  <span style="color: #000066;">shift</span>
<span style="color: #b1b100;">fi</span>
&nbsp;
&nbsp;
<span style="color: #66cc66;">&#91;</span> $<span style="color: #808080; font-style: italic;"># == 2 ] || usage_error &quot;Wrong number of arguments.&quot;</span>
&nbsp;
<span style="color: #0000ff;">svn_dir=</span>`<span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;$1&quot;</span>|sed -e <span style="color: #ff0000;">'s#/$##'</span>`
<span style="color: #0000ff;">replacement_dir=</span>`<span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;$2&quot;</span>|sed -e <span style="color: #ff0000;">'s#/$##'</span>`
<span style="color: #0000ff;">begin_path=</span><span style="color: #0000ff;">$PWD</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#if [ &quot;${svn_dir:0:1}&quot; != &quot;/&quot; ]; then svn_dir=&quot;$PWD/$svn_dir&quot;; fi</span>
<span style="color: #808080; font-style: italic;">#if [ &quot;${replacement_dir:0:1}&quot; != &quot;/&quot; ]; then replacement_dir=&quot;$PWD/$replacement_dir&quot;; fi</span>
&nbsp;
<span style="color: #66cc66;">&#91;</span> -d <span style="color: #ff0000;">&quot;$svn_dir&quot;</span> <span style="color: #66cc66;">&#93;</span> || usage_error <span style="color: #ff0000;">&quot;$svn_dir is not a directory.&quot;</span>
<span style="color: #66cc66;">&#91;</span> -d <span style="color: #ff0000;">&quot;$replacement_dir&quot;</span> <span style="color: #66cc66;">&#93;</span> || usage_error <span style="color: #ff0000;">&quot;$replacement_dir is not a directory.&quot;</span>
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;"># Create all subdirectories in $svn_dir that do not yet exist</span>
<span style="color: #000066;">cd</span> <span style="color: #0000ff;">$replacement_dir</span>
find . -mindepth <span style="color: #cc66cc;">1</span> -<span style="color: #000066;">type</span> d -print | sed -e <span style="color: #ff0000;">'s#^./##'</span> | <span style="color: #b1b100;">while</span> <span style="color: #000066;">read</span> d; <span style="color: #b1b100;">do</span>
    <span style="color: #000066;">cd</span> <span style="color: #0000ff;">$begin_path</span>/<span style="color: #0000ff;">$svn_dir</span>
    <span style="color: #808080; font-style: italic;"># Doesn't the destination directory already exist?</span>
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> ! -d <span style="color: #ff0000;">&quot;$d&quot;</span> <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
        run_command <span style="color: #ff0000;">&quot;svn mkdir '$d'&quot;</span>
    <span style="color: #b1b100;">fi</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Copy all files from $replacement_dir to $svn_dir</span>
<span style="color: #000066;">cd</span> <span style="color: #0000ff;">$begin_path</span>/<span style="color: #0000ff;">$replacement_dir</span>
find . -<span style="color: #000066;">type</span> f -print | sed -e <span style="color: #ff0000;">'s#^./##'</span> | <span style="color: #b1b100;">while</span> <span style="color: #000066;">read</span> f; <span style="color: #b1b100;">do</span>
    <span style="color: #000066;">cd</span> <span style="color: #0000ff;">$begin_path</span>
    run_command <span style="color: #ff0000;">&quot;cp '$replacement_dir/$f' '$svn_dir/$f'&quot;</span> <span style="color: #808080; font-style: italic;"># FIXME: Quoting problem</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Remove all files that do no longer exist in $replacement dir</span>
<span style="color: #000066;">cd</span> <span style="color: #0000ff;">$begin_path</span>/<span style="color: #0000ff;">$svn_dir</span>
find . -<span style="color: #000066;">type</span> f -print | grep -v <span style="color: #ff0000;">'.svn'</span> | <span style="color: #b1b100;">while</span> <span style="color: #000066;">read</span> f; <span style="color: #b1b100;">do</span>
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> ! -f <span style="color: #ff0000;">&quot;$begin_path/$replacement_dir/$f&quot;</span> <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
        run_command <span style="color: #ff0000;">&quot;svn rm '$f'&quot;</span>
    <span style="color: #b1b100;">fi</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Remove all subdirs that do no longer exist in $replacement dir</span>
<span style="color: #000066;">cd</span> <span style="color: #0000ff;">$begin_path</span>/<span style="color: #0000ff;">$svn_dir</span>
find . -mindepth <span style="color: #cc66cc;">1</span> -<span style="color: #000066;">type</span> d -print | grep -v <span style="color: #ff0000;">'.svn'</span> | <span style="color: #b1b100;">while</span> <span style="color: #000066;">read</span> d; <span style="color: #b1b100;">do</span>
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> ! -d <span style="color: #ff0000;">&quot;$begin_path/$replacement_dir/$d&quot;</span> <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
        run_command <span style="color: #ff0000;">&quot;svn rm '$d'&quot;</span>
    <span style="color: #b1b100;">fi</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #000066;">exit</span> <span style="color: #cc66cc;">0</span></pre>

<p>Using the script is simple:</p>

<pre class="bash">svn-replace-dir simple-tags new-simple-tags|less -R</pre>

<p>It replaces all the contents of the first directory (<q><tt>simple-tags</tt></q> in the example) with those of the second directory and it deletes everything that is no longer present in the second dir. In the process, it does all the necessary calls to <tt>svn mkdir</tt>, <tt>svn rm</tt> and (in the next version) <tt>svn add</tt>.</p>

<p><tt>diff</tt> tells me that the script has done its work correctly:</p>

<pre class="bash">diff -x .svn -ruN simple-tags new-simple-tags
<span style="color: #808080; font-style: italic;"># Emptiness is bliss :-) </span></pre>

<p>This is another one of these occasions when Git would have made life so much easier. Luckily, at least there&#8217;s GitHub to host this script as a Gist. <a href="http://gist.github.com/276574">Check there</a> if you want to fetch the newest version of this script.</p> ]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2010/01/14/svn-replace-dir/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tracking WordPress in a Subversion vendor branch</title>
		<link>http://blog.bigsmoke.us/2009/09/20/svn-vendor-branches-wordpress</link>
		<comments>http://blog.bigsmoke.us/2009/09/20/svn-vendor-branches-wordpress#comments</comments>
		<pubDate>Sun, 20 Sep 2009 11:03:34 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=824</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>Two months prior to writing a <a href="http://blog.bigsmoke.us/2009/07/20/svn-vendor-branches">script to upgrade MediaWiki installations using Subversion vendor branches</a>, I wrote something similar for WordPress. It&#8217;s a little bit more limited and should really incorporate some of the improvements made for the MediaWiki version, but it worked fine so far:</p>

<pre class="bash">cat upgrade-wordpress.sh 
<span style="color: #808080; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #0000ff;">svn_repo_url=</span>file:///var/svn/blog.omega-research.org/vendor/wordpress/
<span style="color: #0000ff;">last_version=</span>$<span style="color: #cc66cc;">1</span>
<span style="color: #0000ff;">new_version=</span>$<span style="color: #cc66cc;">2</span>
&nbsp;
<span style="color: #0000ff;">tmp_dir=</span>`mktemp -d`
<span style="color: #000066;">cd</span> <span style="color: #0000ff;">$tmp_dir</span>
&nbsp;
<span style="color: #b1b100;">for</span> version <span style="color: #b1b100;">in</span> $*; <span style="color: #b1b100;">do</span>
    <span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;Downloading and extracting WordPress version $version...&quot;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> -z `svn ls <span style="color: #0000ff;">$svn_repo_url</span>|grep <span style="color: #0000ff;">$version</span>` <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
        <span style="color: #0000ff;">branch=</span>`<span style="color: #000066;">echo</span> <span style="color: #0000ff;">$version</span> |sed -e <span style="color: #ff0000;">'s/<span style="color: #000099; font-weight: bold;">\.</span>[0-9]<span style="color: #000099; font-weight: bold;">\+</span>$//'</span>`
        <span style="color: #0000ff;">archive_file=</span><span style="color: #ff0000;">&quot;wordpress-$version.tar.gz&quot;</span>
        <span style="color: #0000ff;">md5_file=</span><span style="color: #ff0000;">&quot;wordpress-$version.md5&quot;</span>
&nbsp;
        wget <span style="color: #ff0000;">&quot;http://wordpress.org/$md5_file&quot;</span>
        wget <span style="color: #ff0000;">&quot;http://wordpress.org/$archive_file&quot;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> `md5sum <span style="color: #0000ff;">$archive_file</span> |cut -f <span style="color: #cc66cc;">1</span> -d <span style="color: #ff0000;">' '</span>` != `cat <span style="color: #0000ff;">$md5_file</span>` <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
            <span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;MD5 sum did not match!&quot;</span> &gt;&amp;<span style="color: #cc66cc;">2</span>
            <span style="color: #000066;">exit</span> <span style="color: #cc66cc;">1</span>
        <span style="color: #b1b100;">fi</span>
&nbsp;
        tar --extract --ungzip --transform <span style="color: #ff0000;">&quot;s/^wordpress/$version/&quot;</span> --file <span style="color: #0000ff;">$archive_file</span>
        svn_load_dirs.pl <span style="color: #0000ff;">$svn_repo_url</span> -t <span style="color: #0000ff;">$version</span> current <span style="color: #0000ff;">$version</span>
    <span style="color: #b1b100;">fi</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #000066;">cd</span> -
svn merge <span style="color: #ff0000;">&quot;$svn_repo_url$last_version&quot;</span> <span style="color: #ff0000;">&quot;$svn_repo_url$new_version&quot;</span> .</pre>

<p>I&#8217;m actually planning to make both scripts a little bit more generic (in the sense that <tt>svn_repo_url</tt> becomes an external param) and to track future changes to them using GitHub&#8217;s <a href="http://gist.github.com/">Gist</a>. (How ironic is that, tracking an script for Subversion using Git?)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2009/09/20/svn-vendor-branches-wordpress/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Tracking MediaWiki in a Subversion vendor branch</title>
		<link>http://blog.bigsmoke.us/2009/07/20/svn-vendor-branches</link>
		<comments>http://blog.bigsmoke.us/2009/07/20/svn-vendor-branches#comments</comments>
		<pubDate>Mon, 20 Jul 2009 12:33:44 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[MediaWiki]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=672</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>Vendor branches are the proper™ way of merging upstream changes in your web application installations. In Subversion, <a href="http://svnbook.red-bean.com/en/1.4/svn.advanced.vendorbr.html">managing vendor branches</a> isn&#8217;t so easy as it is in Git. Still, vendor branches make it much easier to track upstream.</p> 

<p>From before I first deployed the <a href="http://wiki.omega-research.org/Main_Page">Omega Research Wiki</a>, I already used svn to track changes to my MediaWiki installation. However, for upgrading from one upstream release to the next, I <a href="http://blog.bigsmoke.us/2008/03/13/upgrading-web-apps-with-diff-and-patch">used diff and patch</a>. This isn&#8217;t the most reliable of methods as is exemplified by doing a diff comparing a fresh MediaWiki download with the actual files in my repo (which are supposed to belong to the same version).</p>

<p>What&#8217;s basically a shortcoming of svn is that I can&#8217;t just say:</p>

<pre class="bash">svn merge http://svn.wikimedia.org/svnroot/mediawiki/tags/REL1_15_0/phase3/ \
http://svn.wikimedia.org/svnroot/mediawiki/tags/REL1_15_1/phase3/ .</pre>

<p>This would have been incredibly helpful, because now I&#8217;m keeping a vendor branch not because of local modifications to upstream, but just to be able to merge cleanly.</p>

<p>In Subversion, maintaining a vendor branch by hand is quite some work, because you need to do a checkout first before you can import each version. (My working copy is normally a checkout of <tt>/trunk</tt>, not of <tt>/vendor/mediawiki</tt>.) Luckily, Subversion is distributed with a handy Perl script, <tt>svn_load_dirs.pl</tt>, which can do most of the heavy lifting.</p>

<p>Still, I didn&#8217;t feel like having to do to many manual steps, such as typing in the painfully long URLs for merging, so I decided to wrap the whole process into a nice little Bash script:</p>

<pre class="bash">cat upgrade-mediawiki.sh
<span style="color: #808080; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #0000ff;">svn_repo_url=</span>file:///var/svn/wiki.omega-research.org/vendor/mediawiki/
&nbsp;
<span style="color: #0000ff;">merge=</span><span style="color: #cc66cc;">1</span>
<span style="color: #b1b100;">while</span> <span style="color: #66cc66;">&#91;</span> $<span style="color: #808080; font-style: italic;"># -gt 2 ] # Process extra options</span>
<span style="color: #b1b100;">do</span>
    <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #b1b100;">in</span>
        --no-merge<span style="color: #66cc66;">&#41;</span>
            <span style="color: #0000ff;">merge=</span><span style="color: #cc66cc;">0</span>
            ;;
    <span style="color: #b1b100;">esac</span>
    <span style="color: #000066;">shift</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> $<span style="color: #808080; font-style: italic;"># -ne 2 ]; then</span>
    <span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;Usage: $0 [--no-merge] version version&quot;</span>
    <span style="color: #000066;">exit</span> <span style="color: #cc66cc;">1</span>
<span style="color: #b1b100;">fi</span>
&nbsp;
<span style="color: #0000ff;">last_version=</span>$<span style="color: #cc66cc;">1</span>
<span style="color: #0000ff;">new_version=</span>$<span style="color: #cc66cc;">2</span>
&nbsp;
<span style="color: #0000ff;">tmp_dir=</span>`mktemp -d`
<span style="color: #000066;">cd</span> <span style="color: #0000ff;">$tmp_dir</span>
&nbsp;
<span style="color: #b1b100;">for</span> version <span style="color: #b1b100;">in</span> $*; <span style="color: #b1b100;">do</span>
    <span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;Downloading and extracting MediaWiki version $version...&quot;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> -z `svn ls <span style="color: #0000ff;">$svn_repo_url</span>|grep <span style="color: #0000ff;">$version</span>` <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
        <span style="color: #0000ff;">branch=</span>`<span style="color: #000066;">echo</span> <span style="color: #0000ff;">$version</span> |sed -e <span style="color: #ff0000;">'s/<span style="color: #000099; font-weight: bold;">\.</span>[0-9]<span style="color: #000099; font-weight: bold;">\+</span>$//'</span>`
        <span style="color: #0000ff;">download_file=</span><span style="color: #ff0000;">&quot;mediawiki-$version.tar.gz&quot;</span>
        <span style="color: #0000ff;">download_url=</span><span style="color: #ff0000;">&quot;http://download.wikimedia.org/mediawiki/$branch/$download_file&quot;</span>
&nbsp;
        wget <span style="color: #0000ff;">$download_url</span> || <span style="color: #66cc66;">&#123;</span> <span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;Downloading $download_file failed&quot;</span>&gt;&amp;<span style="color: #cc66cc;">2</span>; <span style="color: #000066;">exit</span> <span style="color: #cc66cc;">1</span>; <span style="color: #66cc66;">&#125;</span>
        tar --extract --ungzip --transform <span style="color: #ff0000;">'s/^mediawiki-//'</span> --file <span style="color: #0000ff;">$download_file</span>
        svn_load_dirs.pl <span style="color: #0000ff;">$svn_repo_url</span> -t <span style="color: #0000ff;">$version</span> current <span style="color: #0000ff;">$version</span>
    <span style="color: #b1b100;">fi</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #000066;">cd</span> -
<span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> <span style="color: #0000ff;">$merge</span> == <span style="color: #ff0000;">'1'</span> <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
    svn merge <span style="color: #ff0000;">&quot;$svn_repo_url$last_version&quot;</span> <span style="color: #ff0000;">&quot;$svn_repo_url$new_version&quot;</span> .
<span style="color: #b1b100;">fi</span>
&nbsp;
<span style="color: #000066;">exit</span> <span style="color: #cc66cc;">0</span></pre>

<p>The script only downloads and imports each specified version if that version doesn&#8217;t already exist in <tt>/vendor/mediawiki/</tt>. Also, because it has a <tt>--no-merge</tt> option, you can download all the old versions of MediaWiki that you&#8217;ve ever used, so that you can go back and compare old versions of your installation with the factory version. Of course, this is only useful if you were already tracking your installation in svn at the time, and even then not really. <img src='http://blog.bigsmoke.us/wp-factory/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>

<p>Anyway, the important thing is that you can use the script to download the version you&#8217;re running now and the version you want to upgrade too. I wanted to make a big jump, from 1.11.1 to 1.15.0 (I had put of the upgrade for a long time, because I first wanted to learn more about vendor branches):</p>

<p>Of course, as always, you need to check if the patch went well. My own results were a vivid demonstration of the unreliability of my previous method:</p>

<pre class="bash">svn st|grep <span style="color: #ff0000;">'^C'</span></pre>

<pre>
C      languages/messages/MessagesKrj.php
C      languages/messages/MessagesWar.php
C      languages/messages/MessagesSe.php
C      languages/messages/MessagesFrc.php
</pre>

<p>Luckily, these were all files I was sure I hadn&#8217;t modified:</p>

<pre class="bash"><span style="color: #b1b100;">for</span> i <span style="color: #b1b100;">in</span> `svn st|grep <span style="color: #ff0000;">'^C'</span>|sed -e <span style="color: #ff0000;">'s/^C //'</span>`; <span style="color: #b1b100;">do</span> mv <span style="color: #0000ff;">$i</span>.merge-right.r32 <span style="color: #0000ff;">$i</span>; svn resolved <span style="color: #0000ff;">$i</span>; <span style="color: #b1b100;">done</span></pre>

<pre>
Resolved conflicted state of 'languages/messages/MessagesKrj.php'
Resolved conflicted state of 'languages/messages/MessagesWar.php'
Resolved conflicted state of 'languages/messages/MessagesSe.php'
Resolved conflicted state of 'languages/messages/MessagesFrc.php'
</pre>

<p>Apparently, a previous upgrade hadn&#8217;t turned my MediaWiki installation <em>exactly</em> into 1.11.1.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2009/07/20/svn-vendor-branches/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Styling XML SVN logs with CSS</title>
		<link>http://blog.bigsmoke.us/2009/05/26/styling-xml-svn-logs-with-css</link>
		<comments>http://blog.bigsmoke.us/2009/05/26/styling-xml-svn-logs-with-css#comments</comments>
		<pubDate>Tue, 26 May 2009 08:22:53 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[sed]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=518</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>My friend, <a href="/author/halfgaar">Wiebe</a>, keeps <a href="http://www.halfgaar.net/">his website</a> in <a href="http://subversion.tigris.org/">Subversion</a>. (Always keep your project files in version management or you&#8217;ll be sorry.) He used to manually track the date with the last significant change in each file (because who cares about typos, right?). But, of course, he kept forgetting to update this when he actually made such changes. So, he decided that he wanted to publish the full SVN log for each page.</p>

<p>The raw SVN logs are a bit <em>raw</em>, reason enough to try to turn it in something prettier. Luckily, there&#8217;s no need to parse the log files, because <tt>svn log</tt> has a command-line option, <tt>--xml</tt>. This option causes the log file to be printed in a simple XML format:</p>

<pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="font-weight: bold; color: black;">?&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;log<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;logentry</span> <span style="color: #000066;">revision</span>=<span style="color: #ff0000;">&quot;345&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;author<span style="font-weight: bold; color: black;">&gt;</span></span></span>halfgaar<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/author<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;date<span style="font-weight: bold; color: black;">&gt;</span></span></span>2009-05-25T10:50:07.560914Z<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/date<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;msg<span style="font-weight: bold; color: black;">&gt;</span></span></span>Added very useful note to index about an awkward sentence.
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/msg<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/logentry<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #808080; font-style: italic;">&lt;!-- Snipped the rest of the logentry elements --&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/log<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre>

<p>Now we can use any number of ready-to-use XML tools to process this log, but I figured that, maybe, a <em>very</em> simple solution could work: CSS. Cascasing Stylesheets can be used for more than just styling HTML. One of the few differences is that with non-HTML XML, there are no defaults for the CSS properties (and aren&#8217;t we always trying to discover and override the various browser-specific CSS defaults anyway?)</p> 

<p>First, we want to add a <tt>&lt;?xml-stylesheet?&gt;</tt> processing instruction to the log file:</p>

<pre class="bash">svn log --xml example_file.xhtml | sed -e <span style="color: #ff0000;">'/&lt;<span style="color: #000099; font-weight: bold;">\?</span>xml / a&lt;?xml-stylesheet type=&quot;text/css&quot; media=&quot;screen&quot; href=&quot;/css/svn-log.css&quot;?&gt;'</span></pre>

<p>The XML file now references the CSS file that we&#8217;re going to make:</p>

<pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="font-weight: bold; color: black;">?&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;?xml</span>-stylesheet <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">media</span>=<span style="color: #ff0000;">&quot;screen&quot;</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;svn-log.css&quot;</span><span style="font-weight: bold; color: black;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #808080; font-style: italic;">&lt;!-- snip --&gt;</span></span></pre>

<p><tt>svn-log.css:</tt></p>

<pre class="css">log <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">background-color</span>: <span style="color: #993333;">white</span>;
  <span style="color: #000000; font-weight: bold;">background-image</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'http://svn.collab.net/repos/svn/trunk/notes/logo/256-colour/subversion_logo-200x173.png'</span><span style="color: #66cc66;">&#41;</span>;
  <span style="color: #000000; font-weight: bold;">background-attachment</span>: <span style="color: #993333;">fixed</span>;
  <span style="color: #000000; font-weight: bold;">background-position</span>: <span style="color: #000000; font-weight: bold;">bottom</span> <span style="color: #000000; font-weight: bold;">right</span>;
  <span style="color: #000000; font-weight: bold;">background-repeat</span>: <span style="color: #993333;">no-repeat</span>;
  <span style="color: #000000; font-weight: bold;">display</span>: <span style="color: #993333;">block</span>;
  <span style="color: #000000; font-weight: bold;">margin</span>: 2em 204px 2em 5ex;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
logentry <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">display</span>: <span style="color: #993333;">list-item</span>;
  <span style="color: #000000; font-weight: bold;">list-style-type</span>: <span style="color: #993333;">square</span>;
  <span style="color: #000000; font-weight: bold;">margin-bottom</span>: 1em;
  <span style="color: #000000; font-weight: bold;">font-family</span>: <span style="color: #993333;">monospace</span>;
  <span style="color: #000000; font-weight: bold;">font-size</span>: <span style="color: #993333;">normal</span>;
  <span style="color: #000000; font-weight: bold;">color</span>: #<span style="color: #cc66cc;">999</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
author <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">display</span>: <span style="color: #993333;">none</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
date <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">display</span>: <span style="color: #993333;">block</span>;
  <span style="color: #000000; font-weight: bold;">width</span>: 10ex;
  <span style="color: #808080; font-style: italic;">/* If Firefox would support font families even when you force a font,
     I could use 'overflow: hidden' to hide everything except the date part of &lt;date&gt;. */</span>
  <span style="color: #000000; font-weight: bold;">overflow</span>: <span style="color: #993333;">hidden</span>;
  <span style="color: #000000; font-weight: bold;">overflow</span>: <span style="color: #993333;">visible</span>; 
  <span style="color: #000000; font-weight: bold;">font-family</span>: <span style="color: #993333;">monospace</span>;
  <span style="color: #000000; font-weight: bold;">font-weight</span>: <span style="color: #993333;">bold</span>;
  <span style="color: #000000; font-weight: bold;">font-size</span>: <span style="color: #cc66cc;">110</span>%;
  <span style="color: #000000; font-weight: bold;">color</span>: #7488a7;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
msg <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">display</span>: <span style="color: #993333;">block</span>;
  <span style="color: #000000; font-weight: bold;">white-space</span>: pre-wrap;
  <span style="color: #000000; font-weight: bold;">color</span>: <span style="color: #000000; font-weight: bold;">black</span>;
<span style="color: #66cc66;">&#125;</span></pre>

<p>We now have a nicely formatted log file. Other things you could do:</p>

<ul>
<li>Add styles for printing (in a separate stylesheet or by using <tt>@media</tt> blocks).</li>
<li>Display the revision author instead of hiding it.</li>
</ul>

<p>Of course, you could do all this and much more with XSLT, but that&#8217;s just all too obvious. <img src='http://blog.bigsmoke.us/wp-factory/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>

<p>If you want to see the stylesheet in action, take a look at <a href="http://www.halfgaar.net/">Wiebe&#8217;s website</a> and look for a <q>View revision log of this page</q> link in the footer of any of his pages.</p>

<div id="attachment_522" class="wp-caption alignnone" style="width: 310px"><a rel="lightbox" title="XML SVN log styled with CSS" href="http://blog.bigsmoke.us/uploads/2009/05/xml-svn-log-styled-with-css.png"><img src="http://blog.bigsmoke.us/uploads/2009/05/xml-svn-log-styled-with-css-300x207.png" alt="XML SVN log styled with CSS" title="XML SVN log styled with CSS" width="300" height="207" class="size-medium wp-image-522" /></a><p class="wp-caption-text">XML SVN log styled with CSS</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2009/05/26/styling-xml-svn-logs-with-css/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Silent change in URLs of Ruby on Rails svn repository</title>
		<link>http://blog.bigsmoke.us/2009/02/19/silent-change-in-urls-of-ruby-on-rails-svn-repository</link>
		<comments>http://blog.bigsmoke.us/2009/02/19/silent-change-in-urls-of-ruby-on-rails-svn-repository#comments</comments>
		<pubDate>Thu, 19 Feb 2009 13:41:11 +0000</pubDate>
		<dc:creator>halfgaar</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[URL]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=413</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>
I don&#8217;t know why, but everything associated with Ruby on Rails seems to change all the time, without notice, or (in the case of URLs) without redirect.
</p>

<p>
We used <tt>http://svn.rubyonrails.org/</tt>rails for our <tt>svn:external</tt> deployment of rails 1.2.6. But that suddenly stopped working. The Ruby on Rails weblog doesn&#8217;t contain any information on it (that I can find), going to <tt>svn.rubyonrails.org</tt> with my web browser yielded just the front page of the weblog and Googling didn&#8217;t help much. That is, until I accidentally found <tt>http://dev.rubyonrails.org/svn/rails</tt>.
</p>

<p>
So, I changed the <tt>svn:externals</tt> from &#8220;<tt>rails http://svn.rubyonrails.org/rails/tags/rel_1-2-6/</tt>&#8221; to &#8220;<tt>rails http://dev.rubyonrails.org/svn/rails/tags/rel_1-2-6/</tt>&#8221; and now it works again.
</p>]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2009/02/19/silent-change-in-urls-of-ruby-on-rails-svn-repository/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Untangling WordPress&#8217; core files from your local customizations</title>
		<link>http://blog.bigsmoke.us/2009/01/30/separating-wordpress-factory-files-from-custom-files</link>
		<comments>http://blog.bigsmoke.us/2009/01/30/separating-wordpress-factory-files-from-custom-files#comments</comments>
		<pubDate>Fri, 30 Jan 2009 12:38:13 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[BigSmoke.US]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=113</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>Since <a href="http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory">version 2.6</a>, WordPress can be <a href="http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory">installed in its own directory</a>, separate from your customizations and everthing. Needless to say, this makes upgrading a whole lot easier.</p>

<p>If, in the pre-2.6 days, you wanted to fetch your WordPress updates through SVN, the docs would <a href="http://codex.wordpress.org/Installing/Updating_WordPress_with_Subversion">advice</a> you to do an <tt>svn checkout</tt> from the official WP SVN repo in your working dir and then do an <tt>svn update</tt> whenever you want to update WordPress. This works because <tt>svn update</tt> leaves local modifcations alone. However, this means that you&#8217;ll be unable to commit your local changes (configuration, themes, plugins, etc.) if you choose this route.</p>

<p>I used my own subversion repository for my blogs and thus had to upgrade the old fashioned way with each release (although I prefer <a href="http://blog.bigsmoke.us/2008/03/13/upgrading-web-apps-with-diff-and-patch">diff/patch over rm/cp</a>). (I could have used <a href="http://svnbook.red-bean.com/en/1.5/svn.advanced.vendorbr.html">vendor branches</a>, but, clearly, I hadn&#8217;t thought about that at the time.) This was pretty much a royal pain in the ass, so I was glad when I could move WordPress into a separate directory with its 2.6 release.</p>

<p>This process consisted of removing everything except <tt>wp-content/</tt>, <tt>wp-config.php</tt>, <tt>.htaccess</tt>. (I also kept <tt>robots.txt</tt>, <tt>favicon.ico</tt> and some other personal files.) Then, I added the current WordPress release as an <tt>svn:external</tt>.</p>

<pre>
svn propset svn:externals 'wp-factory http://svn.automattic.com/wordpress/tags/2.6.1' .
</pre>

<h2><kbd>.htaccess</kbd> changes</h2>

<p>In the WordPress codex, it is then <a href="http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory">suggested</a> to copy <tt>index.php</tt> to the root dir and to change it to require <tt>wp-factory/wp-blog-header.php</tt> instead of <tt>./wp-blog-header.php</tt>. I preferred adding some mod_rewrite voodoo of my own to <tt>.htaccess</tt>, so I did:</p>

<pre class="php">&lt;IfModule mod_rewrite.c&gt;
<span style="color: #808080; font-style: italic;"># This way I don't need directory indices</span>
RewriteRule ^$ /wp-factory/index.php <span style="color: #66cc66;">&#91;</span>L<span style="color: #66cc66;">&#93;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># This way WordPress can manage its own block without doing any harm</span>
RewriteRule ^index.php /wp-factory/index.php <span style="color: #66cc66;">&#91;</span>L<span style="color: #66cc66;">&#93;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Allow easier access to /wp-factory/wp-admin/</span>
RewriteRule ^wp-admin http:<span style="color: #808080; font-style: italic;">//%{HTTP_HOST}/wp-factory/wp-admin/ [L,R=301]</span>
&lt;/IfModule&gt;</pre>

<p>The middle rule performs most of the magic. It redirects all the requests to <tt>/index.php</tt> to the factory default <tt>index.php</tt>. This means that I can let WordPress pretend that <tt>index.php</tt> does live in the root, so I don&#8217;t have to modify the rewrite rules that are managed by WordPress itself:</p>

<pre class="php"><span style="color: #808080; font-style: italic;"># BEGIN WordPress</span>
&lt;IfModule mod_rewrite.c&gt;
RewriteEngine On
RewriteBase /
RewriteCond %<span style="color: #66cc66;">&#123;</span>REQUEST_FILENAME<span style="color: #66cc66;">&#125;</span> !-f
RewriteCond %<span style="color: #66cc66;">&#123;</span>REQUEST_FILENAME<span style="color: #66cc66;">&#125;</span> !-d
RewriteRule . /index.php <span style="color: #66cc66;">&#91;</span>L<span style="color: #66cc66;">&#93;</span>
&lt;/IfModule&gt;
<span style="color: #808080; font-style: italic;"># END WordPress </span></pre>

<h2><tt>wp-config.php</tt> changes</h2>

<p>In <cite><a href="http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory">Giving WordPress Its Own Directory</a></cite> in the WordPress Codex, it is suggested to change the &#8220;<tt>siteurl</tt>&#8221; and &#8220;<tt>home</tt>&#8221; options through the administration panel. In my case they would have to be changed to &#8220;<tt>http://blog.bigsmoke.us/wp-factory/</tt>&#8221; and <tt>http://blog.bigsmoke.us</tt>&#8220;. I couldn&#8217;t do this because I override these with <tt>WP_SITEURL</tt> and <tt>WP_HOME</tt> in my <tt>wp-config.php</tt>. This is because I <a href="http://blog.bigsmoke.us/2008/07/12/separate-development-environment-for-wordpress">configured WordPress to support a development environment separate from the live production environment</a>.</p>

<p>Ignoring the customizations for my development environment, these are the relevant settings in <tt>wp-config.php</tt>:</p>

<pre class="php"><a href="http://www.php.net/define"><span style="color: #000066;">define</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'WP_HOME'</span>, <span style="color: #ff0000;">'http://blog.bigsmoke.us'</span><span style="color: #66cc66;">&#41;</span>;
<a href="http://www.php.net/define"><span style="color: #000066;">define</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'WP_SITEURL'</span>, WP_HOME . <span style="color: #ff0000;">'/wp-factory'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<a href="http://www.php.net/define"><span style="color: #000066;">define</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'WP_CONTENT_DIR'</span>, <a href="http://www.php.net/dirname"><span style="color: #000066;">dirname</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">__FILE__</span><span style="color: #66cc66;">&#41;</span> . <span style="color: #ff0000;">'/wp-content'</span><span style="color: #66cc66;">&#41;</span>;
<a href="http://www.php.net/define"><span style="color: #000066;">define</span></a><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'WP_CONTENT_URL'</span>, WP_HOME . <span style="color: #ff0000;">'/wp-content'</span><span style="color: #66cc66;">&#41;</span>;</pre>

<p>BTW: I really like it how WordPress disables the form controls for <tt>siteurl</tt> and <tt>home</tt> when you override these settings in <tt>wp-config.php</tt>. Kudos for that, devs!</p>

<h2>Next time: git</h2>

<p>In the end, this is all quite a bit of pain to compensate for what is essentially a version management problem. That&#8217;s why, on my newer projects, I&#8217;m now using git which makes forking and tracking an upstream repo absolutely trivial. <img src='http://blog.bigsmoke.us/wp-factory/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>

<h2>A few references</h2>

<ul>
<li><cite><a href="http://codex.wordpress.org/Editing_wp-config.php">Editing wp-config.php</a></cite> in the <cite>WordPress Codex</cite></li>
<li><cite><a href="http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory">
Giving WordPress its Own Directory While Leaving Your Blog in the Root Directory</a></cite> in the <cite>WordPress Codex</cite></li>
<li><cite><a href="http://svnbook.red-bean.com/en/1.5/svn.advanced.vendorbr.html">Vendor branches</a></cite> in the <cite>Subversion Redbook</cite></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2009/01/30/separating-wordpress-factory-files-from-custom-files/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Using diff and patch to upgrade web application installations</title>
		<link>http://blog.bigsmoke.us/2008/03/13/upgrading-web-apps-with-diff-and-patch</link>
		<comments>http://blog.bigsmoke.us/2008/03/13/upgrading-web-apps-with-diff-and-patch#comments</comments>
		<pubDate>Thu, 13 Mar 2008 20:38:46 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[diff]]></category>
		<category><![CDATA[patch]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/2008/03/13/upgrading-web-apps-with-diff-and-patch</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><b>Update (July 30, 2008):</b> I added information about making sure that the patch was successful.</p>

<p>When you install a big-ass web application such as WordPress or MediaWiki, you usually end with a bunch of configuration files and customizations (skins/themes, extension/plugins, uploads, etc.). This makes upgrading the files that come with the application a bit tricky. There&#8217;s a simple solution, however, which work regardless of whether you use a revision control system or not.</p>

<p>First of all, you do, of course, always need a revision control system. I personally recommend Git or Subversion, which are both excellent tools. But, that&#8217;s not what this post is about. I&#8217;m going to use two simple tools which are uniformly available on all (Unixy) platforms: diff and patch.</p>

<p>The procedure is simple:</p>

<ol>
  <li><p>Download the version of the application which you&#8217;re currently running. For our example, we pretend that this version is extracted into the directory <tt>webapp-1.4.3</tt>.</p></li>
  <li><p>Then, download the version to which you&#8217;d like to upgrade. (We&#8217;re assuming that this version is extracted into the <tt>webapp-1.6.2</tt> directory.)</p></li>
  <li><p>Compare the two versions to create a patch file:</p>
<pre>
$ diff --unified --recursive --new-file webapp-1.4.3 webapp-1.6.2 > webapp-upgrade.diff
</pre>
  </li>
  <li><p>Apply the patch to the installation of said web app:</p>
<pre>
$ cd webapp-installed
$ patch --strip=1 --remove-empty-files < ../webapp-upgrade.diff || echo "Some failures!"
</pre>
</ol>

<h2>Check if everything was patched perfectly</h2>

<p>Now, if the patch command returned a non-zero status (printing <q>Some failures!</q> in the above example), it's time to check which chunks of which files failed. Get a summary by searching all files with an <q><tt>.rej</tt></q> or a <q><tt>.orig</tt></q> suffix:</p>

<pre>$ find . -name "*.rej"</pre>

<p>After manually applying any failed hunks, what's left is to compare your directory containing the patched application to the directory with the contents of the new application archive which you've used to create the patch:</p>

<pre>
$ cd ..
$ diff --unified --recursive --new-file webapp-1.6.2 webapp-installed
</pre>

<h2>Version management</h2>

<p>Your upgrade is done. Now, if your using a revision control system, you just need to check in new files and check out deleted files. In Subversion, I do this quickly using the following command sequence:</p>

<pre>
$ svn status|sed -e '/^\?/!d; s/^\?//'|xargs svn add
$ svn status|sed -e '/^\!/!d; s/^\!//'|xargs svn del
</pre>

<p>If you'd been using Git, you could do this all a little bit more sophisticatedly, but my Git skills are not advanced enough to go around giving others advice. Also, it's nice to learn a generic method before learning more specific tools.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2008/03/13/upgrading-web-apps-with-diff-and-patch/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Upgraded WordPress from 2.1 to 2.3.1</title>
		<link>http://blog.bigsmoke.us/2007/11/26/upgraded-wordpress-from-2.1-to-2.3.1</link>
		<comments>http://blog.bigsmoke.us/2007/11/26/upgraded-wordpress-from-2.1-to-2.3.1#comments</comments>
		<pubDate>Sun, 25 Nov 2007 23:05:07 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[BigSmoke.US]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[blog.bigsmoke.us]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/2007/11/26/upgraded-wordpress-from-2.1-to-2.3.1</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m now on WordPress 2.3.1. It was about time too; I was still on 2.1.</p>

<p>Importing the tags from Ultimate Tag Warrior worked fine. Before upgrading and importing, I quickly patched my local version of WP with a little help from Subversion:</p>

<pre class="bash">$ svn diff http://svn.automattic.com/wordpress/tags/<span style="color: #cc66cc;">2.1</span>/ http://svn.automattic.com/wordpress/tags/<span style="color: #cc66cc;">2.3</span><span style="color: #cc66cc;">.1</span>/ &gt; wp.diff
$ <span style="color: #000066;">cd</span> blog.bigsmoke.us
$ patch --remove-empty-files -p0 &lt; ../wp.diff
$ svn revert wp-config.php
$ svn add `svn status|grep <span style="color: #ff0000;">'^?'</span>|sed -e <span style="color: #ff0000;">'s/<span style="color: #000099; font-weight: bold;">\?</span>//'</span>`
$ svn rm `svn status|grep <span style="color: #ff0000;">'^!'</span>|sed -e <span style="color: #ff0000;">'s/!//'</span>`</pre>

<p>Then, after a few changes to my template files to play nice with WP&#8217;s new built-in tagging system, everything was running again.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2007/11/26/upgraded-wordpress-from-2.1-to-2.3.1/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Replacing the trunk of a Subversion repository with a feature branch</title>
		<link>http://blog.bigsmoke.us/2007/02/25/replace-svn-trunk-with-branch</link>
		<comments>http://blog.bigsmoke.us/2007/02/25/replace-svn-trunk-with-branch#comments</comments>
		<pubDate>Sun, 25 Feb 2007 12:27:02 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Sicirec]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[www.sicirec.org]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/2007/02/25/replace-svn-trunk-with-branch</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>For the <a href="http://www.sicirec.org/">Sicirec website</a>, I use <a href="http://subversion.tigris.org/">Subversion</a> to track all changes. When working on big changes which take more than a day to implement, I follow the <em><a href="http://svnbook.red-bean.com/en/1.2/svn.branchmerge.commonuses.html#svn.branchmerge.commonuses.patterns.feature">Feature Branches</a></em> branching pattern. This pattern means that the trunk remains relatively stable and usable for everyday updates while I can climb in a feature branch whenever I want to work on the big new feature(s).</p>

<p>Subversion&#8217;s merge tracking is non-existent. This means that, when I climb from branch to trunk and back again a lot, I have to manually keep track of all the changes in <tt>trunk/</tt> that I merged into the branch. Every one such change, once merged, loses much of its meaningful history unless I painstakingly merge all the commit messages of the patch into the message of the commit that I do after the merge.</p>

<p>Today, after having maintained a branch for months to keep it somewhat in sync with an every-changing trunk, I&#8217;m at the point of having to merge the branch back into trunk. This is rather nightmarish because there are bound to be the many merge conflicts that I already suffered whenever merging changes from the trunk into the branch and then multiplied some.</p>

<p>To avoid torture, I decided I&#8217;d rather just replace the trunk with my feature branch. This is especially attractive because I then retain the history of the branch which is a little more useful to me than the history of the trunk.</p>

<p>I googled around a bit and could find <a href="http://svn.haxx.se/users/archive-2006-06/0481.shtml">one thread</a> discussing a similar problem. The solution proposed there seemed to involve a few too many steps for my taste, so I did the following:</p>

<pre class="php"><span style="color: #808080; font-style: italic;"># From the working copy of my branch:</span>
$ svn del <a href="http://www.php.net/file"><span style="color: #000066;">file</span></a>:<span style="color: #808080; font-style: italic;">///repos/trunk -m &quot;Temporarily deleted trunk.&quot;</span>
$ svn mv <a href="http://www.php.net/file"><span style="color: #000066;">file</span></a>:<span style="color: #808080; font-style: italic;">///repos/branches/my_branch file:///repos/trunk -m &quot;Moved /branches/my_branch to /trunk&quot;</span>
$ svn <span style="color: #b1b100;">switch</span> <a href="http://www.php.net/file"><span style="color: #000066;">file</span></a>:<span style="color: #808080; font-style: italic;">///repos/trunk </span></pre>

<p>That worked perfectly fine. (Except that I still want automatic merge tracking, dammit!)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2007/02/25/replace-svn-trunk-with-branch/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

