Wednesday 11 April 2012

Setting Up Subversion Source-Control with Assembla and TortoiseSVN

Why Source-Control?
When working on sufficiently-large projects, it's good to be able to keep track of changes with a source-control system (sometimes referred to as "revision control system" or "version-control system" or VCS. Personally I prefer the old term "source-control"). The advantages of using such a system:
  • Keeping track of changes:
    Know who made the changes and when.
    Record changes with appropriate comments ("..hmmm.. why did I make this change..?").
  • Reverting and obtaining previous versions.
  • Managing versions and labels of your code in various history points.
  • Potentially sharing the project with other developers ,working together making tracked changes.
  • Some source-control systems allow tracking bugs and tasks, while associating them to changes made in files.
Many enterprises use commercial source-control systems. Since the majority of my enterprise projects have been on Microsoft environments, in the early days I was using Visual Source Safe (VSS), in later years it's been Team Foundation Server (TFS). Both consist of a source server and client applications which integrate with the Windows domain users and with Visual Studio IDE.

On home projects I prefer to use a more modest source control system, preferably one which I can store online for backups and doesn't require a server running all the time.

Article Level:
Reasonably moderate

Table of Contents
Since this is quite an extensive post, I decided to include a table of contents.
Particles of a Source-Control System
Download List
VCS for Cheap Bastards: Free Open-Source Solutions
My choice: Subversion
The Sky is not the Limit: Store It in the Cloud
My choice: Assembla
Breakdown of the Procedure
Getting Started: Create the Repository Locally
Install preliminary tools
Create a separate repository folder (server)
Move your code to the repository
Create a working folder (client)
Don't keep unnecessary binaries in your repository!
Moving It to the Cloud: Getting Started with Assembla
Create a dump of your local repository
Set up your SVN hosting space
Create a working folder (client)
Improved User Experience
Important note: Know the version of your repository!
Commercial tool: Syncro SVN Client
Free tool with a paid option: Vercue
Use Your Repository Like a Boss: Take It into Visual Studio!
My choice: AnkhSVN
Working side-by-side with TFS: Set your solution's source control
Behind the scenes

Particles of a Source-Control System
Usually on a source-control system the project's code resides in a database on central server (commonly referred to as the "repository"). Clients can connect to the server and retrieve the project's code files from it.

Once a file is retrieved and changed, it's marked as a pending change ("checked-out" in Microsoft's slang). The change can be committed to the repository on the server ("check-in"). In this process the source control system also logs which user committed the change, and attaches an optional relevant comment by that user. Changes in multiple files can be bundled in a single submission (Microsoft calls this a "changeset").
Once the change is submitted to the server, other users can (and should) get up-to-date with the latest version of the changed files.
In most source-control systems, client-side management is integrated into the IDE one way or another.
Some systems (e.g. Microsoft's Visual Source Safe) allow only a single user make changes in a specific file at a time, while others (like Microsoft Team Foundation Server) allow multiple users to make changes concurrently.
Each file's history of changes it kept on the server, thus it can be reverted to any of its previous states. Additional common features usually include the ability to mark all the files in the project with a label (e.g. "Code version 1.3") at some given point in time, thus versions of the entire project can be managed and retrieved. Another option is to duplicate the entire project into a separate directory, thus creating 2 versions which can evolve in different directions. This action is called fork (Microsoft calls it "branch"). Separate forked branches can also be re-merged into one another (surprisingly Microsoft also calls this action "merge").

Download List
Quick link list to the downloads mentioned in this post:
  • TortoiseSVN, A Subversion Windows Explorer integration.
  • Slik SVN, A full command line support of Subversion client and server tools.
  • Syncro SVN Client, A commercial Windows UI Subversion client.
  • Vercue, A free/paid Windows UI Subversion client.
  • Visual SVN, A commercial Visual Studio Subversion integrated client.
  • AnkhSVN,  A free Visual Studio Subversion integrated client.
  • WinMerge, My favourite free code diff tool.

VCS for Cheap Bastards: Free Open-Source Solutions
Git, Mercurial, Bazaar and Subversion (a.k.a SVN, by Apache) are 4 commonly used open-source solutions, each consists of a source-control proprietary repository schema, an API and several compatible tools (clients and server implementations, IDE and desktop integration etc). Some of those tools  are free and some commercially paid. They all also support remote usage over HTTP based on well-documented REST services, thus they can be stored online.
Git and Subversion seem to be the most commonly used repository types. There are many more, which can be seen and compared in this Wikipedia article.

My choice: Subversion
After a short and painful trial with Mercurial and a short shallow glance at Git, I came to the conclusion that Subversion is the more user-friendly of the four options and decided to go with it (thus I won't be writing much about the other solutions).

The Sky is not the Limit: Store It in the Cloud
Why store your code online?
  • It makes sharing it among developers easy.
  • You don't need to run your own VCS repository server.
  • It's always accessible.
  • Easy to connect to your code from more than one machine.
  • It's a reliable backup for your code with all its changes
Where?
Well, the answer to that question partially depends on how private you need your project's code to be; Whether you are working on a private project which should be restricted and secured, or you are working on an open-source project and you have no problem sharing it with the rest of the world.
Other factors are the size of your project, the number of individual users who will be working on it, whether you require additional features (like task/bug tracking) and, of course, how cheap a bastard you are.

There are quite a few websites that offer (some free and some paid) storage of source-control repositories. Many of them are compatible with at least one of the 4 source-control systems listed above.

Here are a few examples I've collected. I marked in yellow the services which provide free storage and keep your code private at the same time:
Where? Free Storage? Supported Repositories Your Code Is..
AssemblaYes (Up to 1 GB)Git, Subversionprivate
beanstalk  No Git, Subversion
private
BerliOS   Yes (Unlimited)
Git, Subversion, Mercurial, CVS
open-source
bitbucket   Yes (Unlimited) Git, Mercurial private 
codesion Yes (Up to 100 MB) Git, Subverion open-source
CodePlex Yes (Unlimited)
Git, Mercurial, Subversion
open-source
Code Spaces No
Git, Subverion
private
dynamsoft No TFS
private
freepository Yes
Subversion
private
github Yes (Unlimited) Git open-source
Google Code Hosting 
Yes (Unlimited)
Git, Mercurial, Subversion open-source
JavaForge Yes (Unlimited)
Git, Mercurial, Subversion
open-source
Kiln Not really Mercurial
private
launchpad Yes (Unlimited) Bazaar open-source
ProjectLocker   Yes (Up to 300 MB) Git, Subverion
private
RiouxSVN   Yes (Up to 50 MB) Subverion
private
SourceForge   Yes (Unlimited) Subversion open-source
Slik SVN   Yes (Up to 100 MB) Subversion
private
unfuddle Yes (Up to 200 MB) Git, Mercurial
private
XP-Dev.com No
Git, Mercurial, Subversion 
private

My choice: Assembla
After reviewing the above options, and a couple more, my clear winner was Assembla:
  • Free, up to 1 GB.
  • Keeping my project private.
  • Supporting Subversion repositories (and Git, but I am willing to forgive them for that).
  • Gets extra points for containing the word Ass in its name.
I have ruled out the popular bitbucket since it supports only Git and Mercurial repositories, and also due to their somewhat unorthodox work methodologies...
bitbucket's unique pairing technique

Breakdown of the Procedure
The process which I'm going to provide here consists of a number of steps. Perhaps not all of them are necessary for you, but I give them fully in order to give a good explanation of how Subversion works locally as well as online:
  1. The starting point: I have my local code in a local standalone folder.
  2. Create an empty local Subversion repository in a local folder.
  3. Copy my code from my local standalone folder into the newly created repository.
  4. Get code from the local repository to an empty folder, which will now be a working code folder associated with the local repository.
  5. Create a dump of the local repository in an archived file.
  6. Create an online Subversion hosting account.
  7. Upload the archived repository to the online hosting service.
  8. Get code from the online repository to an empty local folder. This folder will now be a working code folder associated with the online repository.

Getting Started: Create the Repository Locally
Now that I have chosen my source control implementation type (Subversion, i.e. SVN) and where to store it (Assembla), I need to create an SVN repository of my code.

Install preliminary tools
In order to start working with SVN and produce the repository, the basic binaries need to be installed.
The most common basic implementation is TortoiseSVN. It provides a set of client utilities, including Windows Explorer integration.
There are more user friendly client tools (will talk about those a bit later), but for having the initial essential binaries, this is a good start.
This is all nice and good, but unfortunately TortoiseSVN does not cover the entire range of Subversion client and server tools. A good addition would be a full support of SVN command line tools. There are many implementations for that too. One of which is Slik SVN (which also provides free SVN hosting service, as listed above), and that's the one I'll be using here.

Create a separate repository folder (server)
To get started working in a source-control mode, we now need to split our code location in 2: We need a folder to contain an SVN managed repository database (server), and a work folder where where we can retrieve versions of the files and submit changes to them (client).

The first step is to define an empty folder as a repository folder.
Right-click the designated folder and on the context-menu select TortoiseSVN  Create repository here.
Set an empty folder as a repository folder
If all goes well (and, seriously, if it doesn't at this stage, we need to talk..), TortoiseSVN will add what it needs to make this folder into a kosher repository (currently an empty one), and it even gives a notification about that. For the moment we'll leave it at that and hit OK.
Repository folder created
This folder now acts as our Subversion repository server.

Move your code to the repository
Now to import some code to the empty repository. Doing that is as easy as right-clicking the code's folder and selecting TortoiseSVN  Import...
Import my project into a Subversion repository
Select the location of the repository. This can be a URL of an online Subversion repository, or (in our case, for now), a local folder repository.
Note: This should be a valid URI. Notice the "file:///..." prefix. It's necessary. If you're not sure, just click the "browse" ("...") button next to the textbox and select the repository folder through the UI.
Choose repository folder
Files are transferred to the repository.
Congratulations! Your code in its current state is as of now revision #1.
Note that binary files (built executables in bin and obj folders) were also transferred to the repository. It's usually uncommon practice to include them in the repository (which normally holds just the unbuilt project). We'll handle this later.
Congratulations! Version 1 is created in the repository.

Create a working folder (client)
Hurray! Now we have a copy of our code in a SVN repository database (in a local folder). This repository folder acts as a source or server from which the code can be retrieved, and to which changes can be submitted (by one or more clients).
One important thing to note is that the 2 folders (the repository folder, and the folder from which the code was imported) are not connected at the moment at all. That is, there is no Subversion client-server relation between them. Now it's time to establish this relation.
Actually, a good practice at this stage is to start with an empty folder, and let Subversion manage its content.

To do that, right-click the designated working folder, select SVN Checkout... (notice that this is not the same term as what Microsoft calls "check-out"!  With Microsoft's source-control products, "check out" means open the file locally on the client for editing. Here we mean creating a working code folder).
SVN Checkout on an empty folder
Now choose the repository location. Again, this can be an online URL of an SVN repository, or the local folder, and again this should be a valid URI. Notice the "file:///..." prefix. It's necessary. If you're not sure, just click the "browse" ("...") button next to the textbox and select the repository folder.
Choose repository source and destination folder
The work folder is constructed with files from the repository.
Files are transferred to the working folder
Now the working folder contains the project's code and marked with an icon to show it's connected to the local SVN source control.
The folder is now marked with a proper icon
The files in the working folder are also marked with proper icons reflecting their SVN source control status. Also note the .svn folder which contains revision information.
It's now also possible to directly perform source control actions like "Update" (get the latest version of the file from the repository) or "Commit" (submit changes in the file to the repository).
The content of the folder reflects source-control status
Don't keep unnecessary binaries in your repository!
It's good practice to keep everything you need for your project to build in the repository. It's uncommon to keep the built outputs, which are created in the Bin and Obj folders.
If Subversion adds your binary outputs to the repository, you can easily remove them and set Subversion to ignore them in the future. This can be done by name or extension, at the folder level or at the files level.
All you have to do is right-click the items you wish to remove and ignore, and select:
TortoiseSVN  Unversion and add to ignore list  Delete and ignore items by name (or by extension).
Delete and ignore unneeded items

Moving It to the Cloud: Getting Started with Assembla
It's time to discard the local repository and upload it to the cloud. Most of the steps are pretty self-explanatory, but I'll provide a quick screenshot-illustrated walkthrough with some important commentary.

Create a dump of your local repository
To make it easy to move your entire repository (that includes the project sources, history of tracked changes etc), it's possible to dump it into a backup file first.
This is done with Subversion's command line tool named SvnAdmin.It's included in various Subversion implementations, including Slik SVN mentioned above. The syntax is:
svnadmin dump REPOS_PATH
where REPOS_PATH is the path of your local repository.
In order to dump the data into a file, a command line redirection is used by providing the > symbol followed by a full path to the file.
Here's an example:
svnadmin.exe dump "D:\Users\Alon\Desktop\My Repository" >"c:\MyRepository.bak"
Note that this file is also required by Assembla to be zipped before it's uploaded, to reduce traffic.
Once we have a zipped dump, we're good to go.

Set up your SVN hosting space
Go to Assembla, create an account, confirm it by email and log in (if don't know how to do that, we really need to talk).
Under "My Start" you should "Create your own space". This space will host your repository, so pay attention on the following steps.
Create your own repository space on Assembla
You have the option to create a private project or a public open-source project. The choice is up to you. Since my project is private, I get started with the private option.
Create a private project! (Unless you want your code to be open-source)
On the next step you'll be asked to select the repository type and features. The free options are down there, just scroll down and expand them. There's also a Git option, but I'll pass this time, thank you.
Go for the free repository option (Unless you wish to pay for more)
Next you'll be asked to specify a name for your repository. This is important because this name will be (by default) used in your repository's URL.
Name your repository
Once you have the repository space created, you can go to the Import/Export section and upload the archived repository created as explained above.
Import a dump of your repository
Importing...
Importing...
Once the import is complete, your repository is online. The repository folder we've been working with until now can be discarded, and the clients should be working with the online repository instead.
Note the svn URL field below- this is to be used by Subversion clients from now on.
Congrats! Your repository is now online!
Create a working folder (client)
In order to work with a client on the online repository, we need to create a working folder, just like we did with the local repository.
The first step is similar: Right click the folder and select SVN Checkout...
SVN Checkout on an empty folder (even when the repository is online)
The next step is also similar, just that we're using the URL of our online repository, instead or a local folder URI:
Get the files to the working folder (from online repository)
Since the online repository is on a secure account, we'll have to provide credentials to access it:
Credentials for the online repository
The result is the same, but now our local working folder is connected to an online repository.
The local repository folder can now be discarded.

Improved User Experience
TortoiseSVN (in Windows Exploerer) and Slik SVN (via the command line) provide all the tools I need now to manage my code. It's easy to update a file, submit changes and perform any action on my Subversion repository, both locally and online.
However, in terms of user experience, the situation is far below par. Luckily there are many client solutions. Again, some are paid and some are free open-source. Here is a Wikipedia article with a comprehensive list of  Subversion clients. I have tested a few of those solutions, and I'll list here the 2 which made the best impression so far.

Important note: Know the version of your repository!
One important note when it comes to Subversion repositories: Subversion is being developed by Apache and keeps evolving as a product. There are differences between repositories of version 1.6 and version 1.7.4, and not every tool supports every version. When working with TortoiseSVN or Slik SVN and when creating your repository online or offline, it's good to know which version of Subversion you are working with.
When installing client tools, be sure they support your repository version.

Commercial tool: Syncro SVN Client
Syncro SVN Client is a very nice client Subversion application. It's has a very intuitive and easy to use user interface. It allows management of multiple repositories, both online and offline and supports all the main features of Subversion.
I have tested version 7.2, which was the latest version at the time this post was written, and at the moment the supported Subversion version is 1.6. Thus, for example, it failed to detect my working copy folder with Subversion 1.7.4 as being under source control.
Syncro SVN is a paid commercial tool with a number of license options.
However, in every other aspect, Syncro SVN is a very appealing client tool.
Syncro SVN Repositories Management

Syncro SVN History Management
Free tool with a paid option: Vercue
Yes, it's true Vercue has a paid professional version too with extra features, but on a small scale I tried the free version and was very satisfied with it.
Vercue supports Subversion 1.7.4 (the latest), works fluently with my online and offline repositories. Good intuitive user interface, and everything a Subversion user needs in one place.
For the sake of full disclosure, I must add that the fact that it was developed by a fellow Israeli (although I do not know him) adds a bit to my personal pride and will to promote it. In any case- good work, Adrian!
Vercue - "The Reasonable Subversion Experience"

Use Your Repository Like a Boss: Take It into Visual Studio!
In case you are, like me, working with Visual Studio, going back and forth to an external client application is a bit uncomfortable. Integrating Subversion directly into Visual Studio improves the work experience tremendously. With a good tool at hand, you don't have to leave your development environment at all!

My choice: AnkhSVN
There are 2 leading extensions for Visual Studio: The paid Visual SVN and the free (and awesome!) AnkhSVN. I have tried both, and I am very impressed with AnkhSVN.

AnkhSVN has gone quite a way from being a Visual Studio extension to a full-blown Source-Control plugin working directly from within the IDE. If you've worked with VSS or TFS, working with AnkhSVN would be as easy as cake. Many of the features you're used to are already there just where you'd expect them to be.
Here are a few appetizing screenshots:
Full integration with menus and icons into Solution Explorer / Solution Navigtor

Pending changes window! Yes, just like good ol' TFS...

Commit your pending changes like a boss!

AnkhSVN is a full registered source control plugin

Use your favourite diff tool! (Mine is the free awesome WinMerge)

Working side-by-side with TFS: Set your solution's source control
You may want to open your Subversion-controlled solution in a place where TFS is used (e.g. in your workplace). It's possible to explicitly set your project to know it's under Subversion control (thus automatically load with AnkhSVN and not with the default TFS).
To do this:

Open your Subversion-AnkhSVN-controlled solution in Visual Studio.
In Visual Studio's main menu go to File  Subversion  Change Source Control...
Connect your solution to a specific source control
 In the dialog that pops up, select each of the lines (one for the solution, and one for every project), click the Connect button to make the Connected box checked.
Then click OK to confirm.
Choose to connect both the solution and each of the projects
Once this is done and your solution is saved, whenever you open your solution, even if you do it in an environment where TFS is the default source control plugin, AnkhSVN will take over.
Other solutions will be opened regularly to work with TFS.

Behind the scenes:
This action adds a few lines in the .sln file and in its .csproj files which relate them to the right source-control.
Those lines can also be added manually (although, why?).
Here is an example of what's added to an .sln file:
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyProject", "MyProject.csproj", "{1B12BC2A-4E44-4556-9370-7205C94AD5FE}"
EndProject
Global
GlobalSection(SubversionScc) = preSolution
Svn-Managed = True
Manager = AnkhSVN - Subversion Support for Visual Studio
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1B12BC2A-4E44-4556-9370-7205C94AD5FE}.Debug|x86.ActiveCfg = Debug|x86
{1B12BC2A-4E44-4556-9370-7205C94AD5FE}.Debug|x86.Build.0 = Debug|x86
{1B12BC2A-4E44-4556-9370-7205C94AD5FE}.Release|x86.ActiveCfg = Release|x86
{1B12BC2A-4E44-4556-9370-7205C94AD5FE}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Here is an example of what's added to an .csproj file:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProductVersion>8.0.30703</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{1B12BC2A-4E44-4556-9370-7205C94AD5FE}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>MyProject</RootNamespace>
    <AssemblyName>MyProject</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
    <FileAlignment>512</FileAlignment>
    <SccProjectName>Svn</SccProjectName>
    <SccLocalPath>Svn</SccLocalPath>
    <SccAuxPath>Svn</SccAuxPath>
    <SccProvider>SubversionScc</SccProvider>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <PlatformTarget>x86</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <PlatformTarget>x86</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>



5 comments:

  1. Awesome post. I had to discover all this by myself a while ago. Anyway. Using Mercurial and bitbucket.org now. Try DVCS - it's awesome.

    ReplyDelete
  2. Alon, Adam from Assembla here. Just came across your post and wanted to say great tutorial and thanks for recommending http://www.assembla.com.

    Also, you may want to check out EasySVN - an OS SVN client we built using the Tortoise client. It has all the standard TortoiseSVN commands but has optional features such as:

    Automatic Update an Commit - This turns your local folder into a shared folder. Simply work from your local computer and EasySVN automatically updates and commits everything.

    Share with Assembla - You can create a new folder locally and "share with Assembla" and create a new free Subversion repo immediately from your desktop using the client. EasySVN creates a new repository, checks out a working copy, adds your files, and commits them.

    Share with Team Members - Select “Share with Team Members” for any EasySVN activated folder, enter email addresses, and click share. Existing Assembla users will be matched and added automatically, and new users will receive an invitation and instructions on how to access the shared repository.

    Check out EasySVN page here: http://svn-ref.assembla.com/easysvn.html -- Windows is a stable release and the Mac beta will be available in a week or so.

    Thanks again,

    Adam

    ReplyDelete