<?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>experimentalworks &#187; subversion</title>
	<atom:link href="http://blog.experimentalworks.net/tag/subversion/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.experimentalworks.net</link>
	<description></description>
	<lastBuildDate>Fri, 27 Jan 2012 10:07:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Writing a hg to subversion gate</title>
		<link>http://blog.experimentalworks.net/2009/12/writing-a-hg-to-subversion-gate/</link>
		<comments>http://blog.experimentalworks.net/2009/12/writing-a-hg-to-subversion-gate/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 23:59:04 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Version Control]]></category>
		<category><![CDATA[dvcs]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=318</guid>
		<description><![CDATA[Using a decentralized version control system (DVCS) like Mercurial (hg) or Git as a client for Subversion is very common. With the unique features of a DVCS a developer can have both the features of offline development and local branching while still being able to push to a subversion server. This approach is often ...]]></description>
			<content:encoded><![CDATA[<p>Using a decentralized version control system (DVCS) like Mercurial (hg) or Git as a client for Subversion is very common. With the unique features of a DVCS a developer can have both the features of offline development and local branching while still being able to push to a subversion server. This approach is often used in environments in which subversion is the given version control system. While the approach of using this bi-directional push and pull mechanism, provided by git-svn or hgsubversion, works perfectly for one developer, it has limitations working in a team using the usual DVCS push and pull concepts.</p>
<p>The following article will outline the current limitations of bi-directional dvcs to subversion bridges and shows a simple approach to implement a solution for a certain instance of the problem.</p>
<p><span id="more-318"></span><br />
<strong>The bi-directional bridge</strong><br />
The idea of finding a way to interchange commits back and forth between a DVCS and subversion was born early in the development of tools like Git and Mercurial. The basic idea is easy to grasp. To initialize a repository the DVCS requests all changes between revision 0 and the current HEAD from the subversion server and imports every change as a regular changeset into the local repository of the DVCS. In addition it maintains a mapping between the local, DVCS specific, changeset IDs and the revision numbers in the subversion repository. If a developer wants to push his newly created changesets from it&#8217;s local repository back to subversion, the bridge determines the latest pushed changeset and then iterates over the unpushed changes, committing them bit by bit to the subversion server. </p>
<p>Depending on the DVCS you use it will then delete the local changeset and reimport the comitted changesets from the subversion server to ensure that the changeset contains the right date and comitter information as well as the right mapping to the subversion revisionnumber.</p>
<p><em>Example</em><br />
To clarify what we just discussed. Assume that we are using git-svn. We are importing a subversion repository with just one commit using the command (I won&#8217;t get into detail how to use the command):<br />
<code><br />
 $ git svn clone svn://example.com/repo<br />
</code><br />
This command results in a repository which in our example contains the following commit.<br />
<code><br />
commit 7a730e9187becbe1979059cd9752fdea38e3cd9e<br />
Author: david &gt;david @cffdd316-8dd2-4046-8f43-d0df91842a18&lt;<br />
Date:   Thu Jul 12 19:39:51 2007 +0000</p>
<p>    Crescas in mille millia<br />
</code><br />
Let&#8217;s asusme that we create a new commit on top:<br />
<code><br />
commit 129e0e4239ac4d375f2a2132dee042a27f2fd70c<br />
Author: David S. P. &gt;dsp at php.ent&lt;<br />
Date:   Fri Jul 13 12:23:42 2007 +0000</p>
<p>	First Draft<br />
</code><br />
If we push it using <em>git svn dcommit</em>, it&#8217;ll be committed into subversion and<br />
reimported as:<br />
<code><br />
commit 8200f32f61432004b488d063564ac9dae7bf6827<br />
Author: david &gt;david @cffdd316-8dd2-4046-8f43-d0df91842a18&lt;<br />
Date:   Fri Jul 13 12:23:42 2007 +0000</p>
<p>	First Draft<br />
</code></p>
<p><strong>Limitations</strong><br />
Tools like <em>git-svn</em> or <em>hgsubversion</em> are working perfectly fine as long as you use them just as a subversion client. There is a serious limitation in what you can push and pull from and to a subversion server. Particularly, problems arise if you are using the usual DVCS push and pull method to exchange changesets. Why so? If you push and pull from other DVCS repositories you might have to create a merge. Modern DVCS like Git, Mercurial or Bazaar represent history as a directed acyclic graph (DAG). Therefore a merge is a commit which has two (or more) parents, which means that a merge is the resulting connection of two parallel strands of history. Now this is a very comfortable and powerful way to describe history in parallel development. Sadly subversion doesn&#8217;t handles history and hence merges the same way (at least not priort svn 1.5). As a result, it is not possible to represent the Merge from a DVCS in subversion.</p>
<p>Different bi-directional bridges have different approaches to this problems. Git-svn will commit the Merge but not the commits which are part of the seconds strand of history, while hgsubversion will abort if it has to push a merge. The fact that hgsubversion aborts in case of a merge is our actual problem. We want to use Mercurial and therefore need to find a way to push a merge to subversion.</p>
<p><strong>A usecase</strong><br />
You shouldn&#8217;t care much about these limitations. Usually, people are using the bi-directional bridge locally to be able to do offline commits or bisect a bug. In that case, everything will work fine.</p>
<p>But why do I write a complete blog post about a hg to svn bridge if the problem is already solved? The answer is pretty simple.</p>
<ol>
<li>Imagine you are working in a small team. Everybody in the team knows Mercurial and everybody likes to use it. Moreover you are working offline from time to time, and the members of the team sometimes have to exchange unfinished features with other members. In that case you will probably use Mercurial as your version control system. The problem here is the customer. He dictates the VCS and it has to be Subversion. Now subversion at all is not that bad, but in your particular case, it&#8217;s a huge drawback. You have to find a way to mirror your Mercurial repository to the Subversion server.
</li>
<li>A second use case is that you are working on an OpenSource project which uses github or bitbucket to host it&#8217;s repositories. As you are using the OpenSource framework also at work. You have to use Subversion and you want to use svn:externals to integrate your fancy framework into the existing Subversion repository</li>
</ol>
<p>As you see, there is a use case for DVSC to Subversion mirror. As no such tool exists at the moment, we&#8217;ll try to implement a (frankly, very stupid) mirroring mechanism.</p>
<p><strong>The idea and it&#8217;s limitations</strong><br />
We see that we need to mirror a existing Mercurial repository to Subversion.<br />
We also know that we cannot use the existing tools. Our requirements are the following.</p>
<ol>
<li>Mirror a Mercurial repository into a Subversion repository</li>
<li>Track latest synchronized changeset</li>
<li>Handle merges</li>
</ol>
<p>Note that we would have been able to do this with git-svn, while it&#8217;s not possible to do it with hgsubversion.</p>
<p>A few assumptions about the environment where we want to use our mirroring mechanism helps us to simplify the requirements.</p>
<ol>
<li>We do not need to preserve the author information</li>
<li>We have a central Mercurial repository called Gate</li>
<li>No commit will be done into the repository other than our mirroring (and believe me, things get ulgy for you if you try to&#8230;)</li>
<li>We do not need to preserve all commits</li>
</ol>
<p>So what is the end result? We just need to find a way to push all changesets and just ignore all merged changes, but commit the merge itself. This should be sufficient.</p>
<p>In our particular environment everyone has his own repository, but one person integrates all changes into one repository called the Gate. Commits reaching the gate are committed to Subversion.</p>
<p><strong>The implementation</strong><br />
To make a long story short (it&#8217;s getting late). We are using Mercurials log command and it&#8217;s option to obtain a linear history that can be pushed. To get the the history, we use<br />
<code><br />
	hg log --follow-first<br />
</code><br />
This will return the history omitting all merged changesets but including the merges itself. We silently drop the changesets that were merged, but retain the result. As we need to get just the SHA-1, we use the &#8211;template option to get the node. We then iterate over the history, updating our working copy to each changeset in the history, adding all newly created files and deleting all removed files and then comitting the current state of the working directory. So here is our final script<br />
<code></p>
<pre>
#!/bin/sh

lc=0
cont=0
if test -f "LAST_COMMIT"
then
	lc=`cat LAST_COMMIT`
	cont=1
fi

for hash in `hg log --follow-first --template "{node}\n" -r $lc:tip`
	do
		if test $cont -eq 1
		then
			cont=0
			continue
		fi

		echo "update to $hash"
		if ! hg log --template "{desc}\n"  -r $hash > COMMIT_MSG
		then
			echo "Canno get log" >&#038;2
			exit 127;
		fi
		cat COMMIT_MSG

		hg up -C -r $hash
		for file in `hg log --template "{file_adds}\n" -r $hash`
			do
				echo "add $file"
				svn add --parents $file
			done
		for file in `hg log --template "{file_dels}\n" -r $hash`
			do
				echo "del $file"
				svn rm $file
			done
		svn commit -F COMMIT_MSG
		echo $hash > LAST_COMMIT
	done
</pre>
<p></code><br />
It looks scary, and yes it <em>is</em> scary. But for the moment it works. Our simple hg to subversion bridge is finished.</p>
<p class="wp-flattr-button"></p> <p><a href="http://blog.experimentalworks.net/?flattrss_redirect&amp;id=318&amp;md5=5699db1240db9791bfbd9c5808d4f26d" title="Flattr" target="_blank"><img src="http://blog.experimentalworks.net/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2009/12/writing-a-hg-to-subversion-gate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GIT vs. SVN: 2:0</title>
		<link>http://blog.experimentalworks.net/2008/07/git-vs-svn-20/</link>
		<comments>http://blog.experimentalworks.net/2008/07/git-vs-svn-20/#comments</comments>
		<pubDate>Sun, 27 Jul 2008 22:55:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Version Control]]></category>
		<category><![CDATA[dvcs]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://wp.experimentalworks.net/?p=70</guid>
		<description><![CDATA[Again, git vs. SVN. Last time, it was big win for git. And guess what, git will strike again.

I mean nobody is perfect (expect Linus, but there is just one - as he mentioned once), so we actually fail writing bugfree code. Therefore we end up sitting in front of a huge code base ...]]></description>
			<content:encoded><![CDATA[<p>Again, git vs. SVN. Last time, it was big win for git. And guess what, git will strike again.</p>
<p>I mean nobody is perfect (expect Linus, but there is just one &#8211; as he mentioned once), so we actually fail writing bugfree code. Therefore we end up sitting in front of a huge code base trying to figure out what&#8217;s wrong. Thanks to <i>our</i> agile development process we usually end up fixing code we are not into.</p>
<p>So the facts: </p>
<ul>
<li>We don&#8217;t know the code
 </li>
<li>We don&#8217;t have a clue where to search
 </li>
<li>We are lazy
</li>
</ul>
<p><b>bisect</b><br />
Okay, if we drop 1. and 2. we still have to find out what went wrong. So as we tend to get our evening beer fast and don&#8217;t want to waste time, we use <i>git bisect</i> to find out when the problem was introduced.</p>
<p>Assume following commit history:</p>
<p> a &#8211;> a&#8217; (bug introduced) &#8211;> b &#8211;> a&#8221; &#8211;> c</p>
<p>When we <b>bisect</b> the problem, we will end up doing a quick search on the commits, marking buggy commits/trees bad and those that work fine good. This means, we mark <b>c</b> as good, then git will take us to <b>a</b>. We mark that commit as good, which will git move to <b>b</b>. If we mark b bad, git <b>knows</b> that <b>a&#8217;</b> must introduce the bug. Than just view the diff and you might know where to find the bad code and how to fix it.</p>
<p>Well, as long nobody trashed the history with their &#8216;fixed a hundred bugs&#8217; commits, containing like thousends of unrelated changes. In those cases, just bisect your collegue. <b>git vs. SVN: 2:0</b></p>
<p><i>take it with humour</i></p>
<p class="wp-flattr-button"></p> <p><a href="http://blog.experimentalworks.net/?flattrss_redirect&amp;id=70&amp;md5=9bf1b4912119f45b2804a4f4b4ce0071" title="Flattr" target="_blank"><img src="http://blog.experimentalworks.net/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2008/07/git-vs-svn-20/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>GIT vs. SVN: 1 : 0</title>
		<link>http://blog.experimentalworks.net/2008/07/git-vs-svn-1-0/</link>
		<comments>http://blog.experimentalworks.net/2008/07/git-vs-svn-1-0/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 19:44:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Version Control]]></category>
		<category><![CDATA[dvcs]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://wp.experimentalworks.net/?p=69</guid>
		<description><![CDATA[I used git for the last 6 month in a big project. The project itself is not maintained
in git but in subversion as this is what developers know and what project leaders like to use
for several reasons. 

In fact it's not a bad idea to actually use subversion as version control system, particularly if
the ...]]></description>
			<content:encoded><![CDATA[<p>I used git for the last 6 month in a big project. The project itself is not maintained<br />
in git but in subversion as this is what developers know and what project leaders like to use<br />
for several reasons. </p>
<p>In fact it&#8217;s not a bad idea to actually use subversion as version control system, particularly if<br />
the developer are used to it. Well, I don&#8217;t care about that. Thanks to <i>git-svn</i> I could use<br />
<i>git</i> as my <i>subversion</i> frontend. For sure, the distributed architecture of git didn&#8217;t help me that much when it comes to exchanging changes as I was the only developer using git.</p>
<p>But thanks to the repository format and git rich featureset, I found myself using git in a<br />
much more productive way than people could use subversion. </p>
<p><b>Pickaxe:</b><br />
What I really love is pickaxe. You can use that feature by passing -S to git log causing the log<br />
to search for the string in the commit history and display all the commits that contain these changes.<br />
Actually one of our developers had a problem with a blur event in the java script code, causing<br />
all forms in the script to lose their focus all the time. He was just searching for the point all the<br />
time as going through the commit messages was obviously too much time consuming (with about 100 commits per day). To make a long story short: I&#8217;m really a Javascript dumbass, but I just picked the<br />
latest commits having a blur in their name with <i>git log -Sblur</i> and I found 2 promising commits. Showing him the commits actually solved the problem. He just missed one point in the thousands lines<br />
of Javascript containing the blur event that caused the problems. Okay so here are the statistics for that event: Subversion with incremental search, but Javascript knowledge: 3hours. Git without any knowledige and a lazy person using it: 10mins. <b>GIT vs. SVN: 1:0</b></p>
<p class="wp-flattr-button"></p> <p><a href="http://blog.experimentalworks.net/?flattrss_redirect&amp;id=69&amp;md5=6517abdae1adfb424fc230fc5df6d3c8" title="Flattr" target="_blank"><img src="http://blog.experimentalworks.net/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2008/07/git-vs-svn-1-0/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

