<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.dotnet6.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Jeroen</title><subtitle type="html">Perfection is achieved, not when there is nothing left to add, but when there is nothing left to take away.</subtitle><id>http://www.dotnet6.com/blogs/jeroen/atom.aspx</id><link rel="alternate" type="text/html" href="http://www.dotnet6.com/blogs/jeroen/default.aspx" /><link rel="self" type="application/atom+xml" href="http://www.dotnet6.com/blogs/jeroen/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20611.960">Community Server</generator><updated>2008-04-05T13:22:00Z</updated><entry><title>Resharper 4.0 RC is available!</title><link rel="alternate" type="text/html" href="http://www.dotnet6.com/blogs/jeroen/archive/2008/06/06/resharper-4-0-rc-is-available.aspx" /><id>http://www.dotnet6.com/blogs/jeroen/archive/2008/06/06/resharper-4-0-rc-is-available.aspx</id><published>2008-06-06T08:50:00Z</published><updated>2008-06-06T08:50:00Z</updated><content type="html">&lt;p&gt;FINALLY!! Get it here: &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.jetbrains.com/resharper/beta/beta.html" title="http://www.jetbrains.com/resharper/beta/beta.html"&gt;http://www.jetbrains.com/resharper/beta/beta.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.dotnet6.com/aggbug.aspx?PostID=1484" width="1" height="1"&gt;</content><author><name>jeroen</name><uri>http://www.dotnet6.com/members/jeroen.aspx</uri></author></entry><entry><title>Using Subversion in a VSS-only shop </title><link rel="alternate" type="text/html" href="http://www.dotnet6.com/blogs/jeroen/archive/2008/04/05/using-subversion-in-a-vss-only-shop.aspx" /><id>http://www.dotnet6.com/blogs/jeroen/archive/2008/04/05/using-subversion-in-a-vss-only-shop.aspx</id><published>2008-04-05T19:22:00Z</published><updated>2008-04-05T19:22:00Z</updated><content type="html">&lt;p id="zeuc"&gt;Once upon a time, I was used to Visual SourceSafe and the way it handles concurrent versioning problems: if you need to edit a file, you lock it in the VSS &amp;#39;database&amp;#39; (ahum), change it and finally check it back in. If someone else has already placed a lock, tough luck: you have to wait. When you&amp;#39;re alone or in very small teams, that situation does not happen too often, so you can probably live with it. When your team grows however, you really run into trouble, with ugly &amp;#39;dead-lock&amp;#39; situations: I have files that you need, you have files that I need, and we both can&amp;#39;t check in without breaking the build. So you start implementing ways to circumvent the system, making files writable without checking out, with the risk of improper merging, possibly even undoing each other&amp;#39;s changes when not paying enough attention. Been there, done that.&lt;/p&gt;
&lt;p id="m.3_"&gt;Then I learned about how subversion uses a completely different philosophy to tackle this problem, called &amp;#39;copy-modify-merge&amp;#39; (sometimes also called &amp;#39;edit-merge-commit&amp;#39;), as opposed to &amp;#39;lock-modify-unlock&amp;#39;.&amp;nbsp;If you haven&amp;#39;t heard of this before, read&amp;nbsp;&lt;a id="ae92" title="the chapter about versioning models in the svn book" href="http://svnbook.red-bean.com/en/1.4/svn.basic.vsn-models.html"&gt;&lt;font color="#551a8b"&gt;the chapter about versioning models in the svn book&lt;/font&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p id="bzro"&gt;A new world went open, the world of &amp;quot;version control done right&amp;quot;.&lt;/p&gt;
&lt;ul id="abke"&gt;
&lt;li id="m8dk"&gt;
&lt;div id="t430"&gt;Atomic commits (&amp;#39;change sets&amp;#39;) &lt;/div&gt;
&lt;li id="vtmz"&gt;
&lt;div id="uk.p"&gt;Log: &amp;#39;svn log&amp;#39;&amp;nbsp;has become&amp;nbsp;part of my daily toolset. I consider the history of a project almost as important as it&amp;#39;s current state in order to be able to fully understand the code. However, history in VSS is essentially file-oriented, not change-set oriented as in svn. This makes searching in the VSS history&amp;nbsp;awkward and&amp;nbsp;painful. As a result, people typically don&amp;#39;t enter any check-in comments, making the version history even less accessible.&lt;/div&gt;
&lt;li id="x:uw"&gt;
&lt;div id="iwnj"&gt;Blame (or Annotate): there is no such feature in VSS, except again a painful &amp;#39;binary search&amp;#39; through the file&amp;#39;s history (as opposed to a one-click operation&amp;nbsp;with TortoiseSVN)&lt;/div&gt;
&lt;li id="p7tk"&gt;
&lt;div id="h23g"&gt;Easy branching (and merging!)&lt;/div&gt;
&lt;li id="bift"&gt;
&lt;div id="c50h"&gt;Concurrent checkout&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p id="fdz6"&gt;But unfortunately, you don&amp;#39;t always get to choose the version control system to be used. For&amp;nbsp;my current assignment,&amp;nbsp;VSS is a given. Obviously, as a new team member you can&amp;#39;t simply come in and change the version control system they&amp;#39;re used to working with for 5 years: such a conversion is a project on it&amp;#39;s own. &lt;/p&gt;
&lt;p id="shrf"&gt;So&amp;nbsp;I started thinking: wouldn&amp;#39;t it be nice to set up a local svn repository for my own use, so I can work in some isolation, and&amp;nbsp;take advantage of&amp;nbsp;at least some of the powerful svn functionality?&amp;nbsp;&lt;/p&gt;
&lt;h2 id="sv45"&gt;&lt;font size="3"&gt;Scope&lt;/font&gt;&lt;/h2&gt;
&lt;p id="qwfl"&gt;First, let&amp;#39;s elaborate a bit on what we&amp;#39;re trying to do here: the idea is obviously&amp;nbsp;not to replace VSS. Instead, I want a local svn repository, where I&amp;nbsp;can leverage some subversion functionality. First and foremost, I wanted to get rid of the &amp;#39;lock-modify-unlock&amp;#39; hassle, and second, I wanted a better view on the history, especially&amp;nbsp;for my own changes and, as far as possible, also on the changes made by other team members.&lt;/p&gt;
&lt;p id="wl6q"&gt;So&amp;nbsp;how could we implement this?&amp;nbsp;Here is how I went along:&lt;/p&gt;
&lt;ul id="j4-t"&gt;
&lt;li id="srwq"&gt;
&lt;div id="v52l"&gt;I set up&amp;nbsp;a local subversion repository, in which I imported the sources from VSS&amp;nbsp;&lt;/div&gt;
&lt;li id="mpdw"&gt;
&lt;div id="ykst"&gt;I set up a &amp;#39;VSS+SVN&amp;#39; working copy, which I use to synchronize changes back and forth between VSS and svn&lt;/div&gt;
&lt;li id="x883"&gt;
&lt;div id="fgyd"&gt;Finally, I have a&amp;nbsp;&amp;#39;svn-only&amp;#39; working copy, in which I do my day-to-day development work&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id="pnor"&gt;&lt;font size="3"&gt;A note about local svn repositories&lt;/font&gt;&lt;/h2&gt;
&lt;p id="n3gs"&gt;It&amp;#39;s a little-known fact that you don&amp;#39;t really need a subversion server to make use of subversion. Subversion repositories can be accessed in essentially three ways:&lt;/p&gt;
&lt;ul id="z26e"&gt;
&lt;li id="bxw-"&gt;
&lt;div id="fwe8"&gt;using the native svn:// (or svn+ssh) protocol through &lt;i id="ucuu"&gt;svnserve&lt;/i&gt;&lt;/div&gt;
&lt;li id="pk4h"&gt;
&lt;div id="ybyv"&gt;using http(s):// through apache&lt;/div&gt;
&lt;li id="o_sz"&gt;
&lt;div id="e_im"&gt;using the &lt;a id="i:lk"&gt;file:///&lt;/a&gt;&amp;nbsp;protocol&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p id="iump"&gt;The last option is not&amp;nbsp;very well known, I guess since it&amp;#39;s only useful in single-user environments, but since we&amp;#39;re going to be the only physical user accessing this repo, that&amp;#39;s good enough for our purposes. Of course, if you already have a server set up that you can use for this, that will do also, but I will be explaining the case where we use a simple &lt;a id="ajnw"&gt;file:///&lt;/a&gt; repository. And what&amp;#39;s more, the repository format is identical to a repository served through svnserve or apache. So if you would want to migrate later to a real server, you&amp;nbsp;could simply copy the repository to your server and serve it from there.&lt;/p&gt;
&lt;h2 id="my5f"&gt;&lt;font size="4"&gt;Preparations&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/h2&gt;
&lt;p id="huo6"&gt;Let me start with&amp;nbsp;a little warning: if you&amp;#39;re not really comfortable in using svn yet, then don&amp;#39;t start with this immediately on a live project. Make sure you really understand what you&amp;#39;re doing first. If you don&amp;#39;t really understand everything in what follows, learn more about svn first and come back when you&amp;#39;re ready. You don&amp;#39;t want to accidently revert changes from your team members in VSS... However, if you&amp;#39;re reasonably familiar with subversion, you should be just fine. So in what follows, I will assume that this is the case, and that you have your favourite subversion client already installed (for most people this will be either &lt;a id="nid9" title="TortoiseSVN" href="http://tortoisesvn.net/"&gt;&lt;font color="#551a8b"&gt;TortoiseSVN&lt;/font&gt;&lt;/a&gt; or the svn command line client, which you can download &lt;a id="s.yc" title="here" href="http://subversion.tigris.org/"&gt;&lt;font color="#551a8b"&gt;here&lt;/font&gt;&lt;/a&gt;&amp;nbsp;or &lt;a id="bd:g" title="here" href="http://www.open.collab.net/"&gt;&lt;font color="#551a8b"&gt;here&lt;/font&gt;&lt;/a&gt;).&amp;nbsp;For the sake of this article, our project in VSS will be called MyProject (how original, yes I know). &lt;/p&gt;
&lt;h3 id="qawd"&gt;&lt;font size="3"&gt;Creating a repository&amp;nbsp;&lt;/font&gt;&lt;/h3&gt;
&lt;p id="bfsa"&gt;The first step is to create a local repository for your project. If you&amp;#39;re a command line person, you probably know &lt;a class="" href="http://svnbook.red-bean.com/en/1.4/svn.reposadmin.create.html"&gt;how that works using svnadmin&lt;/a&gt;. With TortoiseSVN, simply create a root folder (e.g. C:\SvnRepository, right-click on it in Windows Explorer and select &amp;quot;create repository here&amp;quot;).&lt;/p&gt;
&lt;p id="ms9a"&gt;The structure of the repository does not really matter at this point. For my own use, I typically set up a &amp;quot;single repository for multiple projects&amp;quot;, and I first create a &amp;#39;template&amp;#39; project with a trunk, tags and branches subfolder which I can then simply copy when I want to create a new project. But feel free to use any other repository layout you&amp;#39;re comfortable with.&lt;/p&gt;
&lt;h3 id="fj_e"&gt;&lt;font size="3"&gt;Importing the sources from VSS into SVN&lt;/font&gt;&lt;/h3&gt;
&lt;p id="eoa5"&gt;Now we&amp;nbsp;can import the sources from VSS into our local SVN repository. Start by checking out your (still empty) project trunk from SVN into a folder on your local system, e.g. C:\Projects\MyProject\VSS. Yes, that&amp;#39;s right, VSS. Bear with me.&lt;/p&gt;
&lt;p id="tw3z"&gt;Now,&amp;nbsp;use VSS to &amp;quot;Get&amp;nbsp;Latest Version&amp;quot;&amp;nbsp;the sources from VSS into that very same folder. &amp;#39;Add&amp;#39; all relevant sources to svn. Make sure to exclude all VSS-specific files (*.scc, *.vspscc, *.vssscc, ...), and some other Visual Studio-specific files that are not needed (like *.csproj.user, *.suo, the bin and obj folders, ...). Review what you&amp;#39;ve added before committing the files to svn.&lt;/p&gt;
&lt;p id="g-5h"&gt;What we have now is a svn repository containing all sources of our project, and a combined vss+svn working copy which we&amp;#39;re going to use to synchronize our local svn repository with the VSS database.&lt;/p&gt;
&lt;h3 id="b20g"&gt;&lt;font size="3"&gt;Setting up our &amp;#39;real&amp;#39; working copy&lt;/font&gt;&lt;/h3&gt;
&lt;p id="jbvk"&gt;Next to svn/vss working copy, we need one for our own developments, too. That&amp;#39;s easy of course, simply perform an &amp;#39;svn checkout&amp;#39; into a second working copy (e.g. C:\Projects\MyProject\SVN).&lt;/p&gt;
&lt;h3 id="mchs"&gt;&lt;font size="3"&gt;Synchronizing external changes (VSS -&amp;gt; SVN)&lt;/font&gt;&lt;/h3&gt;
&lt;p id="ynmh"&gt;This is the easier part. To mirror the changes committed into VSS by any team member, you can use&amp;nbsp;the following procedure:&amp;nbsp;&lt;/p&gt;
&lt;ul id="ew8c"&gt;
&lt;li id="dpel"&gt;
&lt;div id="he_d"&gt;Do a recursive VSS &amp;#39;Get Latest Version&amp;#39; in the VSS working copy. VSS will make all files in the svn+vss working copy read-only.&lt;/div&gt;
&lt;li id="blak"&gt;
&lt;div id="l3vn"&gt;Since our working copy is both linked with VSS and SVN at the same time, any files changed in VSS (by other users) will be automatically picked up as &amp;#39;modified&amp;#39; by svn. However, when files are added or deleted from VSS, we still need to communicate this to svn. With TortoiseSVN this is easy (if you don&amp;#39;t care about renames/moves): just open the commit dialog and check the &amp;#39;Select All&amp;#39;&amp;nbsp; checkbox at the bottom. &lt;/div&gt;
&lt;li id="wolf"&gt;
&lt;div id="m-5f"&gt;Commit, with a nice little comment of course (at least put something like &amp;#39;update from VSS&amp;#39;). &lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p id="s9bx"&gt;These steps&amp;nbsp;can also be easily automated this&amp;nbsp;in a batch script similar to the following (you need command line svn installed and in the path to make this work; also obviously you&amp;#39;ll need to adjust some variables to adapt it to your own environment:&lt;/p&gt;
&lt;blockquote id="ao1b" dir="ltr" style="MARGIN-RIGHT:0px;"&gt;
&lt;p&gt;&lt;font face="courier new,courier"&gt;REM set some variables&amp;nbsp; &lt;br /&gt;set SSDIR=path\to\VSS\ (folder containing srcsafe.ini)&lt;br /&gt;set SS=path\to\SS.EXE&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="courier new,courier"&gt;REM move to VSS+SVN working folder&lt;br /&gt;pushd C:\Projects\MyProject\VSS&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="courier new,courier"&gt;REM get latest version (recursively)&lt;br /&gt;%SS% GET $/path/to/MyProject/In/VSS -R -O- &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="courier new,courier"&gt;REM svn add new files, svn delete disappeared files&lt;br /&gt;for /f &amp;quot;tokens=2&amp;quot; %%i in ( &amp;#39;svn status ^| findstr /R &amp;quot;^\?&amp;quot;&amp;#39;) do svn add %%i&lt;br id="ed4y" /&gt;for /f &amp;quot;tokens=2&amp;quot; %%i in ( &amp;#39;svn status ^| findstr /R &amp;quot;^\!&amp;quot;&amp;#39;) do svn del %%i&lt;/font&gt;&lt;/p&gt;
&lt;p id="rxeh"&gt;&lt;font face="courier new,courier"&gt;svn commit -m &amp;quot;got latest version (vss)&amp;quot;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;popd&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;div id="plow"&gt;As a last step, we still need to update our &amp;#39;real&amp;#39; (svn only) working copy. I keep this step manual, since I like to have control over when changes are actually copied over to my working copy; SVN will then merge the external changes, possibly marking any files which have been modified in VSS (by other users) and in our SVN working copy as &amp;#39;conflicted&amp;#39;. First advantage of the system: you get to decide yourself when to merge external changes into your working copy (since VSS does a &amp;#39;Get Latest Version&amp;#39; on check-out, you often need to do a full Get Latest Version of the project, which you may not yet be ready for).&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;font size="3"&gt;&lt;strong&gt;Checking in your changes into VSS: bridging svn to vss&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;
&lt;p id="rdyr"&gt;As&amp;nbsp;said before, we use a &amp;#39;svn-only&amp;#39;&amp;nbsp;working copy to develop our features/bug fixes. Whenever a feature is ready to be committed, we can commit it to our local svn, but obviously we also have to make sure that we also check it properly into VSS. This is a little tricky, since here is where we need to bridge the gap between the svn &amp;#39;copy-modify-merge&amp;#39; and vss &amp;#39;lock-modify-unlock&amp;#39; philosophies. &lt;/p&gt;
&lt;p&gt;In a subversion environment, this is a matter of doing an &amp;#39;svn commit&amp;#39;; if that fails because of an out-of-date conflict, we need to do an &amp;#39;svn update&amp;#39; first, then resolve conflicts (if any), build and test and try to commit again; repeat until the commit passes. With VSS however, we need to make sure we have all files checked out before we can start modifying them. &lt;/p&gt;
&lt;p&gt;The steps needed to do the &amp;#39;svn update&amp;#39; part in our VSS+SVN environment are described above (vss -&amp;gt; svn). But the &amp;#39;svn commit&amp;#39; part is now to be replaced by a &amp;#39;VSS check in&amp;#39;. To be able to do so, we first need to explicitly check out the needed files in VSS. &lt;/p&gt;
&lt;p&gt;Now wat do we want to achieve here? We want to merge our change from our svn-only working copy into our vss+svn working copy, where we can check things into VSS. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div&gt;Check out all files from VSS into our vss+svn working copy. VSS will get the latest version, which may cause a final &amp;#39;vss2svn&amp;#39; synchronization step. For files that are locked by someone else, we&amp;#39;re still blocked,&amp;nbsp;however it&amp;#39;s now easier for me to simply &amp;#39;undo checkout&amp;#39; if needed. &lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Once we have all files checked out in VSS, we can do the commit from our svn-only working copy, and update our vss+svn working copy. This effectively merges our change into the VSS working copy.&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Finally, we can check things into VSS.&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p id="q55b"&gt;&lt;font size="3"&gt;&lt;strong&gt;Benefits&lt;/strong&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now this may seem quite some work, and it is to some extent.&amp;nbsp;However, you do get some nice functionality in return:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div&gt;first and foremost, you get rid of the checkout-modify-checkin burden&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;you can do your own developments in some isolation (of course it remains a best practice to integrate the work of your colleages early and often, but at least you&amp;#39;re calling the shots now instead of VSS)&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;you get a much more powerful, changeset-based &amp;#39;svn log&amp;#39;, and &amp;#39;svn annotate&amp;#39; &lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;it becomes really easy to reverse previous change sets (impossible with VSS), or go back to a previous revision of the project (possible but awkward with VSS)&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;branching: e.g. you can create your own private feature branches, if you want&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;For example, we&amp;#39;re currently finalizing a release, while the next release will be dedicated to upgrading to VS2008/.Net 2.0 (from VS2003/.Net 1.1). So we&amp;#39;ve created a branch in subversion to perform the necessary changes for the upgrade, while other team members can still work on finalizing the release. When the release is done, we will merge the changes from the feature branch back into VSS.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;jeroen&lt;/p&gt;&lt;img src="http://www.dotnet6.com/aggbug.aspx?PostID=1423" width="1" height="1"&gt;</content><author><name>jeroen</name><uri>http://www.dotnet6.com/members/jeroen.aspx</uri></author><category term="subversion" scheme="http://www.dotnet6.com/blogs/jeroen/archive/tags/subversion/default.aspx" /><category term="vss" scheme="http://www.dotnet6.com/blogs/jeroen/archive/tags/vss/default.aspx" /></entry></feed>