<?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>thinking in geek &#187; scm</title>
	<atom:link href="http://joshrobb.com/blog/category/scm/feed/" rel="self" type="application/rss+xml" />
	<link>http://joshrobb.com/blog</link>
	<description>tagline's are so web2.0</description>
	<lastBuildDate>Fri, 11 Mar 2011 07:17:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Speeding up git svn on Windows (win32)</title>
		<link>http://joshrobb.com/blog/2010/02/15/speeding-up-git-svn-on-windows-win32/</link>
		<comments>http://joshrobb.com/blog/2010/02/15/speeding-up-git-svn-on-windows-win32/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 11:32:51 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[git]]></category>
		<category><![CDATA[scm]]></category>

		<guid isPermaLink="false">http://joshrobb.com/blog/?p=72</guid>
		<description><![CDATA[Update: This fix is now included in git releases 1.7.0.1 and greater &#8211; for more info &#8211; click here. Update 2: This page incorrectly stated that this patch was included in git 1.7.0.1. It&#8217;s not! It&#8217;s in the git repository&#8217;s &#8220;next&#8221; branch &#8211; which will eventually become the git 1.7.2 series. I&#8217;ll update again when [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update:  </strong> This fix is now included in git <del datetime="2010-06-02T13:35:40+00:00">releases 1.7.0.1 and greater</del> &#8211; for more info &#8211; <a href="/blog/2010/03/01/git-svn-on-windows-speedup-now-released-in-git-1-7-0-1/">click here</a>.</p>
<p><strong>Update 2:  </strong> This page incorrectly stated that this patch was included in git 1.7.0.1. It&#8217;s not! It&#8217;s in the git repository&#8217;s &#8220;next&#8221; branch &#8211; which will eventually become the git 1.7.2 series. I&#8217;ll update again when this is released. </p>
<p>Some people have noticed that using git svn (in my case msysgit) on Windows VM&#8217;s<sup><a href="http://joshrobb.com/blog/2010/02/15/speeding-up-git-svn-on-windows-win32/#footnote_0_72" id="identifier_0_72" class="footnote-link footnote-identifier-link" title="VMWare Fusion WinXP vm under OSX 10.5. This is probably important as people not using git svn on a VM don&amp;#8217;t seem to sufffer such huge perf problems.">1</a></sup> can be incredibly slow. I&#8217;m one of those people. </p>
<p>Running a no-op rebase (i.e. there are no changes @ the svn end) looks like this.<sup><a href="http://joshrobb.com/blog/2010/02/15/speeding-up-git-svn-on-windows-win32/#footnote_1_72" id="identifier_1_72" class="footnote-link footnote-identifier-link" title="[1] My svn server is 350ms away &amp;#8211; AucklandLondon and on a VPN &amp;#8211; I&amp;#8217;m using the SVN protocol to access it &amp;#8211; SVN seems fastest of the SVN protocols.">2</a></sup></p>
<p><code>$ time perl git svn rebase<br />
Current branch master is up to date.</p>
<p>real    2m56.750s<br />
user    0m3.129s<br />
sys     2m39.232s</code></p>
<p>Nearly 3 minutes to verify that my local git svn branch is up to date!</p>
<p>I used to (_many_ years ago) &#8211; do quite a bit of perl for for sysadmin stuff. I&#8217;ve already paid for those sins but this was slow enough that I wanted to see what was causing the problems. </p>
<p>Running perl -d:DProf and collecting a basic trace gave me some interesting info.<sup><a href="http://joshrobb.com/blog/2010/02/15/speeding-up-git-svn-on-windows-win32/#footnote_2_72" id="identifier_2_72" class="footnote-link footnote-identifier-link" title="Total Elapsed Time = 140.4030 Seconds
  User+System Time = 3.919008 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 77.7   3.046  3.046     12   0.2538 0.2538  DynaLoader::dl_load_file
 9.16   0.359  0.359      1   0.3590 0.3590  main::read_repo_config
 6.38   0.250  0.250     18   0.0139 0.0139  Git::_command_common_pipe
 1.22   0.048  3.063     40   0.0012 0.0766  SVN::Base::import
 1.20   0.047  0.156     22   0.0021 0.0071  main::BEGIN
 0.41   0.016  0.016      4   0.0040 0.0040  Exporter::as_heavy
 0.41   0.016  0.032      7   0.0023 0.0046  IO::File::BEGIN
 0.41   0.016  0.016     11   0.0015 0.0015  Git::SVN::BEGIN
 0.41   0.016  0.016      7   0.0023 0.0023  Git::SVN::rev_map_max_norebuild
 0.41   0.016  0.016      7   0.0023 0.0023  SVN::Git::Fetcher::BEGIN
 0.38   0.015  0.015      1   0.0150 0.0150  warnings::BEGIN
 0.38   0.015  0.015      7   0.0021 0.0021  Git::BEGIN
 0.38   0.015  0.015     13   0.0012 0.0011  Error::subs::try
 0.00   0.000  0.000      1   0.0000 0.0000  XSLoader::bootstrap_inherit
 0.00   0.000  0.000      1   0.0000 0.0000  Exporter::Heavy::heavy_export_tags

">3</a></sup> SVN::Base::import (essentially a constructor) was importing all the svn dll entry points (using DynaLoader) every time git svn started up &#8211; which was extremely slow in my environment.</p>
<p>On a hunch<sup><a href="http://joshrobb.com/blog/2010/02/15/speeding-up-git-svn-on-windows-win32/#footnote_3_72" id="identifier_3_72" class="footnote-link footnote-identifier-link" title="git-svn shell&amp;#8217;s out to itself a bunch so it seemed an obvious first step. ">4</a></sup> I moved the code which was require&#8217;ing SVN::Base::import to run lazily (rather than at git-svn startup). </p>
<p><code>$ time perl /libexec/git-core/git-svn rebase<br />
Current branch master is up to date.</p>
<p>real    0m33.407s<br />
user    0m1.409s<br />
sys     0m23.054s<br />
</code><br />
6 times faster! </p>
<p>&#8220;git svn dcommit&#8221; sped up even more. Previously:</p>
<p><code>$ time perl /libexec/git-core/git-svn.orig dcommit -n<br />
Committing to svn://XXXXX/trunk ...<br />
diff-tree befd87ba1b65fa7d86779c3058faf1f4886d7020~1 befd87ba1b65fa7d86779c3058faf1f4886d7020</p>
<p>real    3m7.046s<br />
user    0m3.190s<br />
sys     2m53.897s</code></p>
<p>Afterwards: </p>
<p><code>$ time perl /libexec/git-core/git-svn dcommit -n<br />
Committing to svn://XXXXX/trunk ...<br />
diff-tree befd87ba1b65fa7d86779c3058faf1f4886d7020~1 befd87ba1b65fa7d86779c3058faf1f4886d7020</p>
<p>real    0m10.312s<br />
user    0m1.109s<br />
sys     0m4.632s</code></p>
<p>19 times faster! </p>
<p>For me &#8211; this was enough for now. I&#8217;d spent more time on the issue than I had &#8211; and git svn operations were now fast enough to not totally break my workflow. </p>
<p>I&#8217;ve uploaded the patch here: <a href='http://joshrobb.com/blog/wp-content/uploads/2010/02/git-svn.patch.txt'>git-svn.patch</a></p>
<p>YMMV/No warranty expressed or implied/IANAL etc.  If it breaks your repo/application/life &#8211; don&#8217;t come crying to me. </p>
<p>Thanks to <a href="http://www.fastchicken.co.nz">Nic Wise</a> for testing this for me and validating my timing data etc. </p>
<ol class="footnotes"><li id="footnote_0_72" class="footnote">VMWare Fusion WinXP vm under OSX 10.5. This is probably important as people not using git svn on a VM don&#8217;t seem to sufffer such huge perf problems.</li><li id="footnote_1_72" class="footnote">[1] My svn server is 350ms away &#8211; Auckland<->London and on a VPN &#8211; I&#8217;m using the SVN protocol to access it &#8211; SVN seems fastest of the SVN protocols.</li><li id="footnote_2_72" class="footnote"><code>Total Elapsed Time = 140.4030 Seconds<br />
  User+System Time = 3.919008 Seconds<br />
Exclusive Times<br />
%Time ExclSec CumulS #Calls sec/call Csec/c  Name<br />
 77.7   3.046  3.046     12   0.2538 0.2538  DynaLoader::dl_load_file<br />
 9.16   0.359  0.359      1   0.3590 0.3590  main::read_repo_config<br />
 6.38   0.250  0.250     18   0.0139 0.0139  Git::_command_common_pipe<br />
 1.22   0.048  3.063     40   0.0012 0.0766  SVN::Base::import<br />
 1.20   0.047  0.156     22   0.0021 0.0071  main::BEGIN<br />
 0.41   0.016  0.016      4   0.0040 0.0040  Exporter::as_heavy<br />
 0.41   0.016  0.032      7   0.0023 0.0046  IO::File::BEGIN<br />
 0.41   0.016  0.016     11   0.0015 0.0015  Git::SVN::BEGIN<br />
 0.41   0.016  0.016      7   0.0023 0.0023  Git::SVN::rev_map_max_norebuild<br />
 0.41   0.016  0.016      7   0.0023 0.0023  SVN::Git::Fetcher::BEGIN<br />
 0.38   0.015  0.015      1   0.0150 0.0150  warnings::BEGIN<br />
 0.38   0.015  0.015      7   0.0021 0.0021  Git::BEGIN<br />
 0.38   0.015  0.015     13   0.0012 0.0011  Error::subs::try<br />
 0.00   0.000  0.000      1   0.0000 0.0000  XSLoader::bootstrap_inherit<br />
 0.00   0.000  0.000      1   0.0000 0.0000  Exporter::Heavy::heavy_export_tags<br />
</code><br />
</li><li id="footnote_3_72" class="footnote">git-svn shell&#8217;s out to itself a bunch so it seemed an obvious first step. </li></ol>]]></content:encoded>
			<wfw:commentRss>http://joshrobb.com/blog/2010/02/15/speeding-up-git-svn-on-windows-win32/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>SVN 1.5</title>
		<link>http://joshrobb.com/blog/2008/06/25/svn-15/</link>
		<comments>http://joshrobb.com/blog/2008/06/25/svn-15/#comments</comments>
		<pubDate>Wed, 25 Jun 2008 12:45:42 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[scm]]></category>

		<guid isPermaLink="false">http://joshrobb.com/blog/?p=55</guid>
		<description><![CDATA[Well &#8211; (finally) Subversion 1.5 is out!Â  For the first time svn has built in support for repeated merges without spuriousÂ conflicts or manually managing the list of previously merged revisions. This is _fantastic_ news. The basis of the merge tracking feature in 1.5 was svnmerge.py which means that many svn users will already have a [...]]]></description>
			<content:encoded><![CDATA[<p>Well &#8211; (finally) <a href="http://subversion.tigris.org/svn_1.5_releasenotes.html">Subversion 1.5</a> is out!Â </p>
<p>For the first time svn has built in support for repeated merges without spuriousÂ conflicts or manually managing the list of previously merged revisions.</p>
<p>This is <em>_fantastic_</em> news. The basis of the merge tracking feature in 1.5 was svnmerge.py which means that many svn users will already have a reasonable idea how it works. (List of merged revisions are stored in svn properties on a branch).Â </p>
<p>I&#8217;ve been watching the development of svn 1.5 for the last 18 months (give or take) crying everyday that I have to manually manage merging work as I oggle the feature list.Â </p>
<p><a href="http://tortoisesvn.net/node/331">TortoiseSVN</a>Â has aÂ significantlyÂ enhanced release as well. I&#8217;m particularlyÂ excited about this because it supports caching the change log which will make a huge difference for me given that my svn server it 2 continents and 300ms away.</p>
<p>It also looks like there may be some progress on cleaning up the working copy implementation.<sup><a href="http://joshrobb.com/blog/2008/06/25/svn-15/#footnote_0_55" id="identifier_0_55" class="footnote-link footnote-identifier-link" title="http://subversion.tigris.org/roadmap.html">1</a></sup>. Which would involve fixing the whole every folder with .svn folders problem (a la git or svk).Â </p>
<ol class="footnotes"><li id="footnote_0_55" class="footnote"><a href="http://subversion.tigris.org/roadmap.html">http://subversion.tigris.org/roadmap.html</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://joshrobb.com/blog/2008/06/25/svn-15/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On merging (svnmerge.py)</title>
		<link>http://joshrobb.com/blog/2007/08/06/on-merging-svnmergepy/</link>
		<comments>http://joshrobb.com/blog/2007/08/06/on-merging-svnmergepy/#comments</comments>
		<pubDate>Mon, 06 Aug 2007 18:05:35 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[scm]]></category>

		<guid isPermaLink="false">http://joshrobb.com/blog/2007/08/06/on-merging-svnmergepy/</guid>
		<description><![CDATA[This subject has come up a few times in the last few days &#8211; I thought I&#8217;d take the opportunity to collect my thoughts from various emails and put them here. Svnmerge.py is a tool which tries to fix the _totally broken_ &#8220;svn merge&#8221; command.Â  Here&#8217;s an example scenario. My repository contains a number of [...]]]></description>
			<content:encoded><![CDATA[<p>This subject has come up a few times in the last few days &#8211; I thought I&#8217;d take the opportunity to collect my thoughts from various emails and put them here.</p>
<p>Svnmerge.py is a tool which tries to fix the _totally broken_ &#8220;svn merge&#8221; command.Â  Here&#8217;s an example scenario. My repository contains a number of branches of the same product:</p>
<p>/trunk &#8211; the main line of development. New features are added here.<br />
/branches/Customer1 &#8211; We made a release to a customer &#8211; this is the version that was released.<br />
/branches/Customer2 &#8211; Another release for a different customer.</p>
<p>/trunk, /Customer1 and /Customer2 all contain bug fixes fixing critical bugs which were discovered in production by different customers. In an ideal world we would be able to get our SCM to list all the changes to Customer1 and choose which ones to apply to /trunk and Customer2. Subversion lets you do this using the merge command.</p>
<blockquote><p>svn merge /branches/Customer1 /trunk</p></blockquote>
<p>What this does is take all the changes to Customer1 which have been made since the branching of Customer1 from trunk and apply them to trunk. The first time this works great. All the changes get made to my working copy and I can go through an commit them and every things groovy.</p>
<p>The next day I have (another) critical bug for Customer1. I fix it &#8211; and commit my change to the Customer1 branch. Then I need to merge again.</p>
<blockquote><p>svn merge /branches/Customer1 /trunk</p></blockquote>
<p><em>What this does is take all the changes to Customer1 which have been made since the branching of Customer1 from trunk and apply them to trunk. </em>Can you see the problem here? If you can&#8217;t let me explain. It will attempt to apply the same changes it applied previously, this will generate conflicts, potentially _lots_ of conflicts. They will need to be manually resolved and then just the new (bug fix) changes committed.</p>
<p>Until next time when svn merge will &#8211; <em>take all the changes to Customer1 which have been made since the branching of Customer1 from trunk and apply them to trunk. </em>ARRG. See what I meant by brain dead?</p>
<p>It actually gets worse. I also want to merge bug fixes from /Customer2 -&gt; /trunk and from Customer1 -&gt; Customer2 and Customer2 -&gt; Customer1. Not to mention the bugs you find while doing development and fix in the trunk that should be merged back to the customer branches. /trunk -&gt; /Customer1 and /trunk -&gt; /Customer2.Â  This is a boat load of manually fixing up conflicts that needs to happen. Every time. It&#8217;s almost easier to manually change the necessary files for each branch.</p>
<p>In all honnesty &#8211; I wouldn&#8217;t try to merge bug fixes from the trunk to branches &#8211; if I found a bug in dev &#8211; I&#8217;d chose a customer branch to fix it in and merge it into the trunk from there. Anything else would be too painful.</p>
<p>How does svnmerge.py help? What svnmerge.py does is store some metadata in your repository (actually &#8211; per branch &#8211; which is part of the problem) about which revisions you&#8217;ve previously merged. This way &#8211; when you use svnmerge &#8211; it will only apply changes to your working copy that have not been previously merged.</p>
<p>Yay &#8211; problem solved right? Unfortunately &#8211; no. There&#8217;s a problem. If you only ever have two branches &#8211; then this will work pretty well. If you have more than two then your stuffed. e.g. /trunk /branches/Customer1 /branches/Customer2 = 3 = bad news.</p>
<p>The reason is thatÂ  svnmerge tracks merges per branch &#8211; it doesn&#8217;t support what the svnmerge guys call graph based merges. A graph based merge looks like the following:</p>
<p>e.g. /Customer1 &lt;-&gt;Â  /Customer2 &lt;-&gt; /trunk &lt;-&gt; /Customer1 (this scenario is described above when merging bugfixes from the trunk to branches).</p>
<p>You have to setup bidirectional merging on each branch.</p>
<p>/branches/Customer1 &lt;-&gt; /trunk<br />
/branches/Customer2 &lt;-&gt; /trunk<br />
/branches/Customer2 &lt;-&gt;  /branches/Customer1</p>
<p>If I merge my fixes from /Customer1 -&gt; trunk then /Customer2 knows nothing about it. When I try and merge all three branches I end up getting conflicts. The problem is that the history is lost when you merge a bugfix Customer1 -&gt; trunk -&gt; Customer2 &#8211; svnmerge only knows change in Customer2 came from the trunk &#8211; not from Customer1. If that change was previously merged Customer1-&gt;Customer2 (critical bug for example) then you&#8217;ll get conflicts again.</p>
]]></content:encoded>
			<wfw:commentRss>http://joshrobb.com/blog/2007/08/06/on-merging-svnmergepy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Git</title>
		<link>http://joshrobb.com/blog/2007/08/01/git/</link>
		<comments>http://joshrobb.com/blog/2007/08/01/git/#comments</comments>
		<pubDate>Wed, 01 Aug 2007 17:34:40 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[scm]]></category>

		<guid isPermaLink="false">http://joshrobb.com/blog/2007/08/01/git/</guid>
		<description><![CDATA[I managed to find some time to watch this today: Tech Talk: Linus Torvalds on git Git is a distributed SCM system &#8211; Linus wrote it in two weeks. It seems like it&#8217;s getting some traction among some of the Rails crowd. Mozilla seriously considered adopting it for Mozilla 2 work but the lack of [...]]]></description>
			<content:encoded><![CDATA[<p>I managed to find some time to watch this today: <a href="http://www.youtube.com/watch?v=4XpnKHJAok8">Tech Talk: Linus Torvalds on git</a></p>
<p><a href="http://git.or.cz/">Git</a> is a distributed SCM system &#8211; Linus wrote it in two weeks. It seems like it&#8217;s getting some traction among some of the Rails crowd. Mozilla seriously considered adopting it for Mozilla 2 work but the lack of a finished win32 client was a show stopper (although progress seems to have been made there).</p>
<p>There&#8217;s nothing like Tortoise for it (yet) &#8211; but it&#8217;s still pretty new &#8211; it&#8217;s been used by the kernel developers for the last two years &#8211; but it seems like it&#8217;s only in the last few months that it&#8217;s got easy enough for newbies to pickup.</p>
<p>Distributed SCM&#8217;s really take some brain twisting to get your head around &#8211; and Git in particular breaks with most conventions that people used to traditional centralised, file based systems are used to. Linus says that he thinks the only reason he&#8217;s been able to build git was because he didn&#8217;t have brain rot caused by exposure to traditional scm tools. <img src='http://joshrobb.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://joshrobb.com/blog/2007/08/01/git/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

