Introduction
This article describes the philosophy behind the Open Source DotSVN library and how the same can be used to connect to a Subversion file repository from .NET applications.
Background
Subversion is the fastest growing version control system in open source projects. The following graph shows the adoption of Subversion on public Apache servers. (This graph has been taken from the CollabNet site, and is based on the data provided by E-Soft.)
As the popularity of Subversion increases, many developers and component vendors are developing applications or components to access Subversion. They would want to programmatically connect to a Subversion repository in order to develop repository browsers, source viewers etc. DotSVN is the .NET library to achieve this in .NET applications.
Architecture of Subversion
The Subversion architecture contains multiple layers, each of which performs a specific task and provides good encapsulation and modularity. Following are the layers:
fs
(file system): This is the lowest layer which implements the versioned file system.repos
(repository): This is the repository layer which implements many helper functions built around the file system.mod_dav_svn
: Provides WebDAV access to the repository.ra
(repository access): This layer handles the repository access, both local and remote.wc
(working copy): This layer manages the local working copies which are local reflections of portions of the repository.client
: This layer uses the working copy library to provide common client tasks like authenticating the user, comparing versions etc.
The following diagram taken from the SVN book depicts the Subversion architecture (courtesy of the SVN book).
The Subversion file system is a three-dimensional file system, two dimensions being the directory view and the third dimension being the revision. In Subversion, files are stored as links to the previous change; hence, the Subversion repository is very compact. Also, the Subversion file system uses transactions to keep the changes atomic - All or None.
What is DotSVN?
DotSVN is a complete .NET implementation of the Subversion. DotSVN accesses a Subversion repository at the repository level itself (instead of at the client side/working copy). It implements the Subversion repository access layer completely in .NET, without using any of the Subversion libraries. It exposes APIs which will help .NET developers to connect to an SVN repository and manipulate it. DotSVN is developed as an Open Source project hosted on Google Code. Recently, the DotSVN team released the first iteration of the DotSVN library, which supports reading the contents of an FSFS repository hosted in Subversion. It can read the directory structure, properties of a revision, and the contents of individual files from the repository. This release of DotSVN also includes a sample application which demonstrates the usage of the DotSVN APIs. This sample application is a WinForms based repository browser, very similar to the repository browser of Tortoise SVN. It displays the contents of an FSFS repository in a hierarchical fashion, displaying the Windows file type icon beside each directory or file.
How to use the DotSVN APIs?
DotSVN APIs are very simple to use. Accessing an SVN repository using DotSVN involves three steps:
- Open the repository
- Do the relevant operations (e.g.: get the directory contents of the repository)
- Close the repository
Let us understand these steps one by one.
Opening the repository
In order to open a repository, we have to specify how we are going to access the repository. A Subversion repository can be accessed by any of the following three protocols:
- file:// To access a repository located on the local machine
- http:// or https:// To access a repository over the Web (using the WebDav protocol)
- svn:// A custom protocol proprietary to Subversion
DotSVN currently supports repository access using the file:// protocol, which is implemented in the FSRepository
class. So, in order to connect to a repository on the local file system, we have to first instantiate an FSRepository
, giving a complete local path to the repository. In DotSVN, the repository access layer is abstracted in the ISVNRepository
interface and the SVNRepository
class. The process of instantiating a repository class is encapsulated in a factory class. The following code snippet demonstrates this:
string repositoryPath = @"file://C:\DummyRepos";
ISVNRepository repository =
SVNRepositoryFactory.Create(new SVNURL(repositoryPath));
Additionally, DotSVN provides a TestConnection
method which can be used to check whether the URL corresponds to a valid repository or not. This method quickly opens and closes the repository with the given URL, and throws an exception if there is any problem in accessing the repository.
private static bool IsValidRepository(string repositoryPath)
{
bool isValid = true;
try
{
repository = SVNRepositoryFactory.Create(new SVNURL(repositoryPath));
repository.TestConnection();
}
catch
{
isValid = false;
}
return isValid;
}
public static void Main()
{
string repositoryPath = @"file://C:\DummyRepos";
if( IsValidRepository(repositoryPath) )
{
repository = SVNRepositoryFactory.Create(new SVNURL(repositoryPath));
repository.OpenRepository();
}
}
Working with the repository
Now that we have learnt how to open a repository, let's do something with the repository using the DotSVN library. For instance, we shall read and display the contents of the repository. The following DotSVN API is the right choice to do this:
public override ICollection<SVNDirEntry> GetDir(string path,
long revision, IDictionary<string, string> properties);
This method fetches the contents and properties of a directory located at the specified path in a particular revision. The information of each directory entry is represented by a single SVNDirEntry
object. A directory entry could be a directory or a file on the file system. The inputs for this method are specified in the first two arguments: the first argument, path
, is the path to the directory whose contents are to be read. This path could either be relative to the repository's location, or absolute to the root (starts with "/"). The second argument, revision
, is the number corresponding to the revision that has to be fetched. The output of the method is provided by the return value and the third argument of the method. The return value is a collection containing the directory entries (SVNDirEntry
objects) fetched from the repository. The third parameter is a set of key-value pairs which represent the properties of the directory. See below for a sample code to do this. This sample uses a custom WinForms control named TreeListView
which combines a tree view and a list view:
long revision = -1;
IDictionary<string, string> properties = new Dictionary<string, string>();
ICollection<SVNDirEntry> dirEntries = repository.GetDir(string.Empty,
revision, properties);
string rootPath = repository.GetRepositoryRoot(true).ToString();
TreeListViewItem rootItem = repositoryTreeView.Items.Add(rootPath, 0);
foreach (SVNDirEntry dirEntry in dirEntries)
{
TreeListViewItem newItem = new TreeListViewItem(dirEntry.Name, 0);
string fileExtension = Path.GetExtension(dirEntry.Name);
newItem.SubItems.Add(fileExtension.TrimStart('.'));
newItem.SubItems.Add(dirEntry.Revision.ToString());
newItem.SubItems.Add(dirEntry.Author);
string size = string.Format("{0}", dirEntry.Size);
newItem.SubItems.Add( size );
string date = dirEntry.Date.ToLocalTime().ToString();
newItem.SubItems.Add(date);
rootItem.Items.Add(newItem);
}
foreach (string property in properties)
{
}
This sample just shows the rough code to display the directory structure in a TreeView
control. It can be further enhanced to display directory nodes prefixed by a "+" icon, or to show the Windows file type icon for files based on their file extensions. All these capabilities are demonstrated in the GUI sample project that comes with the DotSVN source.
Closing the repository
Yeah. That is very simple. Just do this:
repository.CloseRepository();
For a dry run of this sample, download and run the GUI sample attached to this article. You can choose a repository by either giving the complete file:// path to the repository in the URL text box, or just click on the "..." button and browse to a repository root directory. See the above screenshot of the GUI sample application. For details on the implementation, download the GUI sample source attached to this article.
Other APIs in DotSVN
Apart from the APIs described above, DotSVN exposes a few more APIs through the ISVNRepository
interface to manipulate the repository. A few of them are listed below:
string GetRepositoryUUID(bool ForceConnection);
long GetLatestRevision();
long GetFile(string path,
long revision,
IDictionary<string, string> properties,
Stream contents);
Please refer to the documentation in the DotSVN source code for details on the usage of these APIs.
Conclusion
This article has given an overview of the usage of the DotSVN library to access a Subversion repository from a .NET application. A more detailed implementation is available in the sample projects that come with DotSVN. The sample projects include a WinForms sample, console application, and a Web application. The complete source code of DotSVN can be downloaded from the DotSVN project home page. You may also download the DotSVN compiled binaries attached to this article to get the latest built version of the library. You may also check out the latest working copy of the DotSVN source code anonymously, using this link.
References
The best reference to understand the DotSVN library is to read the source code itself. A few more references include:
History
Initial version.