Text

Retrieving changed paths

Retrieving what files where added / deleted / changed in a certain revision can be determined using SvnClient.Log()

using (SvnClient client = new SvnClient())
{
    client.Log(
        reposUri,
        new SvnLogArgs 
        {
            Range = new SvnRevisionRange(9999, 9999)
        },
        (o, e) =>
            {
                foreach (var changeItem in e.ChangedPaths)
                {
                    Console.WriteLine(
                        string.Format(
                            "{0} {1} {2} {3}",
                            changeItem.Action,
                            changeItem.Path,
                            changeItem.CopyFromRevision,
                            changeItem.CopyFromPath));
                }
            });
}
Text

When/why to SvnClient.LoadConfiguration

SvnClient.LoadConfig​urationDefault() (just like svn.exe) assumes the user’s registry hive is always available (e.g. it can read from HKEY_CURRENT_USER). It uses a few windows api calls on retrieving which directory to use for the settings.

When running a website, or another service or similar cases where there is a ‘current user’ but the full user profile hasn’t been loaded, the call can fail after a timeout.

Using .LoadConfiguration(​) skips these procedures as it says: Only load these settings. (+- equivalent to using --config-dir on svn.exe)

Text

Retrieving multiple versions of a file

You can use the client.FileVersions() command to retrieve multiple version of the same file. This fetches one complete file, and all other files using the differences between each revision in a single connection. This should give much better performance than retrieving all files individually with client.Write()

public void WriteRevisions(SvnTarget target,
                       SvnRevision from,
                       SvnRevision to)
{
    using(SvnClient client = new SvnClient())
    {
        SvnFileVersionsArgs ea = new SvnFileVersionsArgs 
            {
                Start = from,
                End = to
            };

        client.File.Versions(target, ea,
            (s, e) =>
                {
                    Debug.WriteLine(e.Revision);
                    e2.WriteTo(...);
                });
    }
}

See method WalkMe (and others) in this testcase to see more details about its usage (Username guest, no password).

Tags: how to
Text

Undoing changes from a revision

If there’s a need to revert changes that were made to in a certain revision or revision range, you need to perform a reverse merge. The basic idea is to reverse the start and end revisions, causing a merge that’s the opposite of the revision itself.

(Reverse) merging can be done with the Merge method. Passing the revision range is done with SvnRevisionRange. For a reverse merge, make sure the startRevision is larger than the endRevision. To undo revision 123, you want to pass (123, 122)

To undo a file in the working copy:

var range = new SvnRevisionRange(revision, 
                                 revision - 1);
client.Merge(path, path, range);

This means that to undo all changes (ie go back to the state at revision, you can use:

 var range = new SvnRevisionRange(SvnRevision.Working, 
                                  revision);
Link

Using SharpSvn and VisualSvn Server to create a management interface

Text

Changing the svn:author property for a revision

The author for each Subversion revision is stored in the svn:author revision property. To change this afterwards, you can use SetRevisionProperty. You also need to make sure that making changes like this one is allowed in the pre-revprop-change repository hook.

using (SvnClient client = new SvnClient())
{
    client.SetRevisionProperty(
        new Uri("http://my/repository"), 
        12345,
        SvnPropertyNames.SvnAuthor,
        "MyName");
}
Link

Nice application of SharpSvn to automate a simple task that can avoid lots of manual labour

Text

Getting file content from repository (in memory)

It’s possible to retrieve files from the repository, and accessing the contents of these files without the need for temp files. To do this, SvnClient.Write can be used:

public void ReadContents(
                         Url url, 
                         Stream stream, 
                         long? revision=null)
{
    // Use the HEAD version when the revision param
    // wasn't specified
    var target = revision == null
        ? new SvnUriTarget(url, SvnRevisionType.Head)
        : new SvnUriTarget(url, revision);

    client.Write(target, stream);
}
Link

Great getting started article

Text

GetStatus and Status

This post will go into how to use GetStatus and Status.

The GetStatus methods retrieve the status for the file(s) and directory(s) specified. This is similar to running svn status on the command line.

GetStatus(String path, 
          out Collection statuses)
GetStatus(String path, 
          SvnStatusArgs args, 
          Collection(SvnStatusEventArgs) statuses)

With this call you pass in a path and optional args, and it will run a recursive status on that path. The path needs to be a valid working copy. The statuses that are encountered during the scan are added to the collection.

You can check the properties of SvnStatusEventArgs to determine the dir/file and its Subversion status. The properties prefixed with Remote are only valid when you’re doing a remote status.

Example:

Collection statuses;
client.GetStatus(path, statuses);
foreach(SvnStatusEventArgs arg in statuses)
{
    Console.WriteLine(arg.LocalContentStatus +
                      " - " + arg.FullPath);
}

To execute a remote status, you need to use the overload with the StatusArgs parameter, and set the ContactRepository property to true:

Collection statuses;
client.GetStatus(path, 
                 new SvnStatusArgs
                 {
                     ContactRepository = true
                 },
                 statuses);
foreach(SvnStatusEventArgs arg in statuses)
{
    Console.WriteLine("Remote status: " + 
                      arg.RemoteContentStatus + 
                      " - " + arg.FullPath);
}

As a general rule in SharpSvn, the Command methods execute the command and call an event handler every time a status is found in this case, whereas the GetCommand calls wait until all statuses are retrieved, adding them to the collection out parameter. It’s using an out parameter because the exception throwing can be (partially) disabled, making the function return false when something went wrong.

For example:

client.Status(
    String path, 
    (sender, ea)
    {
        Console.WriteLine(ea.LocalContentStatus +
                          " - " + ea.FullPath);
    });