Taking programmatic control over SmartSVN

While SmartSVN is running, it can receive commands to be executed, like opening a file compare for a versioned file. This is how the Windows Explorer Integration and the Mac OS X Finder Integration are working. This article will show how to use this socket-based command API for custom integrations of SmartSVN.

First of all, SmartSVN has to be started, either normally or by supplying the --server-mode command line parameter (requires Java 6) which prevents a project window to occur. On Windows you may execute: bin/smartsvn.exe --server-mode. On Unix you may use bin/smartsvn.sh --server-mode. A platform-independent way to start SmartSVN is java --jar smartsvn.jar --server-mode which will work fine on Mac OS X.

Once SmartSVN has been started, it will create a port-file within its settings directory immediately. It contains the port number for client connections. To perform a SmartSVN command, a new socket should be created connecting to this port at host 127.0.0.1, then the communication can start.

The protocol is very simple: The client sends the command name, terminated by \n. Then it sends the absolute file paths to be used by the command, every path on a separate line, terminated by \n. Finally it sends one more empty line, i.e. just \n. For example:

get-states
d:\\working-copy\\a.txt
d:\\working-copy\\b.txt
d:\\working-copy\\c.txt
(empty line)

Note, that the text has to be escaped like character and string literals have to be escaped in Java source code, e.g. on Windows the backslash \ has to be escaped \\.

Depending on the command, SmartSVN will return a response. In case of our get-states example, this could be:

d:\\working-copy\\a.txt <tab> unchanged
d:\\working-copy\\b.txt <tab> unchanged
d:\\working-copy\\c.txt <tab> modified
(empty line)

Here, file a.txt and b.txt are reported as unchanged while file c.txt is modified.

Actually, only the get-states command has a response. For all other commands the socket will be closed immediately after having received the final trailing empty line. Other available commands are:

  • add
  • annotate
  • cleanup
  • commit
  • compare
  • ignore
  • lock
  • unlock
  • log
  • rename
  • remove
  • resolve
  • revert
  • revision-graph
  • update

For example, to open SmartSVN’s File Compare for c.txt, following lines should be sent:

compare
d:\\working-copy/c.txt
(empty line)

When implementing a communication with SmartSVN’s server it may be helpful to set the logging level for the smartsvn.server category to debug. For details refer to the Technical Articles.

The attached Java class contains a complete example implementation, which connects to a running SmartSVN instance, scans a working copy directory for a modified file and then opens the File Compare.

Tips for Migrating from CVS to SVN

I was asked by a couple of CVS users who want to start with SVN (using our SVN client SmartSVN) about some tips how to avoid common pitfalls. So, from my personal experience and from problems we have got reported by our users, I would consider following issues as notable:

With SVN you don’t have tags and branches as a built-in feature like in CVS. Instead, tags and branches are handled by using special paths and SVN’s cheap copy feature. Don’t try to reinvent the wheel but better stick with a default repository layout:

repository-root
[-] project1
| [-] branches
| | [+] branch1
| | [+] branch2
...
| [-] tags
| | [+] tag1
| | [+] tag2
...
| [+] trunk
[-] project2
| [-] branches
| | [+] branch1
| | [+] branch2
...
| [-] tags
| | [+] tag1
| | [+] tag2
...
| [+] trunk
...

Quite often people check out the whole repository or project including all tags and branches. Don’t do that but only check out either the trunk or a specific tag or branch. It is quite easy to “switch” between them.

With CVS it often was common practice to add a certain tag to only a few files. Forget about tagging individual files in SVN.
SVN can tag (aka copy) large parts of the repository as effective as just a small part.
Another advantage of tagging always the full repository is that you are able to switch easily to that project state.
If you have used file-based (not (only) project-based) tags in CVS and history doesn’t really matter to you, better import fresh project states in the SVN repository and don’t convert the CVS repository to SVN.

A lot of projects consist of multiple parts. With CVS you might have used CVS modules or shell scripts to check out from different repository locations or different repositories.
SVN’s externals are a much better concept and should be used instead.

Start Developing Plugin for SmartSVN Enterprise

SmartSVN Enterprise offers a Plugin-API which allows to add own functionality to SmartSVN. In this article I want to show how to configure IntelliJ IDEA to compile a sample plugin and how to launch SmartSVN to load this plugin. Of course you should be able to use any other Java IDE, too.

Ensure that SmartSVN is installed and configured. It must have an Enterprise (demo) license registered. How to get an Enterprise demo license.

Now create a project structure:

  • create an empty directory (we will use C:\projects\mergeInfoColumn) as the root for the project
  • create a lib directory and copy all .jar files from the SmartSVN installation into it (svnkit-cli.jar is not required and hence can be skipped)
  • create a src directory and unpack the mergeInfoColumn directory from the plugin-sources.zip of the SmartSVN installation into it.

Create a new project in IDEA and add a Java module mergeInfoColumn and configure its Sources, Paths and Dependencies according to the following screenshots.

Remember this output path, we will need it later, so SmartSVN can load the plugin:

Every SmartSVN plugin depends on the openapi.jar, the mergeInfoColumn plugin also requires the svnkit.jar to compile:

Open the compiler settings and ensure that .properties files are copied from the sources to the classes directory.

To launch SmartSVN you will need all its jar files, hence we create another module named launcher just for launching purposes.
Add all the .jar files from the lib directory as dependency. To ensure that the mergeInfoColumn module is also compiled before launching, add it also as dependency:

Create a Run/Debug configuration. Use the main class SmartSVN and tell SmartSVN where to look for the plugin classes by setting the VM property smartsvn.pluginLocations. Use the compiler output path configured above. You can use absolute paths, but also, as shown in this screenshot, relative ones.

Now you should be able to launch SmartSVN. If everything is done right, you should see “Plugin … loaded.” message on the console immediately after SmartSVN start up.

SVN vs. Git

I’m now having a couple of years experience in using our SVN-client SmartSVN, but I would not call me an "SVN expert". Since approximately a half year we are using Git to develop our Git-client SmartGit, but I’m definitely neither a Git expert nor an experienced Git user. To be honest, I’m only using the Git features which are available in SmartGit, because I can’t remember all the command line options. Nevertheless, I think I have a good overview over both tools, especially, because I use both for my daily work.

A couple of the following differences might not be just differences between SVN and Git, but differences between classical VCS and distributed VCS (DVCS) in general. Here are some sketched differences in random order which came to my mind when I was asked by a SmartSVN customer:

Git can be used off-line

With SVN you have pristine copies of the files available in the admin-areas which allow, e.g., to see the local uncommitted changes without connection to the SVN server. But if you have to commit your changes, you will need the network connection to the SVN server. With Git you can commit your changes as you like, because you have your own copy of the repository locally available. Only if you want to synchronize your repository with an external one, you need the network connection.

Git has incredible Log performance

Because Git has its own repository locally available, showing a log is a very fast operation. It is not necessary to transfer all the information over network. (We have put quite a lot of effort into SmartSVN’s Log Cache to obtain similar performance.)

Git versions files, SVN also directories

Git, just like CVS, versions only files. You can’t store an empty directory in the repository like with SVN.

Admin files

Git has just one location for its admin files, the .git directory in the root of your working tree. SVN currently scatters its .svn directories over the whole working copy. This makes restructuring (moving or copying) files or directories with Git a no-brainer — with SVN you always have to take care to not move or copy the .svn files to not screw up your working copy. A side-effect is, that reading a Git working tree is much faster than reading a comparably large SVN working copy.

Properties

SVN supports file or directory properties, Git doesn’t. These SVN properties allow, for example, to

  • store patterns for files to be ignored (you can define what files/directories should be ignored, but only using .gitignore files similar to the .cvsignore files in CVS)
  • define the file type for certain files
  • define the line separators which should be used for files
  • define URL patterns for the issue tracker, so an SVN-client like SmartSVN can detect issue numbers in commit messages and show them as links

Encoding

SVN has a clear definition of the encoding to use for storing file names or commit messages in the repository (UTF-8). This makes it very platform-independent.
You can configure Git to use some special encoding, but it does not enforce it. This reduces Gits inherent platform-independence significantly.

Tagging, Branching

SVN does not have a special tag or branch feature, but the ability to create light-weight copies of whole directory structures can be used in combination with a special repository structure to achieve that. Unfortunately, a lot of SVN users don’t follow the standard repository structure suggested by the SVN team and reinvent their own. This makes it hard for tools like SmartSVN to "transparently" support tags and branches.
Git supports tagging and branching as a native feature. In combination with the locally available repository, this has the outstanding advantage that you can create as many local branches you like, e.g. to implement larger features, without the need to store such “shelves” in the central repository.

Multi-Project Repositories

With SVN usually a couple of projects are stored in the same repository, separated only by a certain repository structure. Users can easily check out only certain parts of a larger repository. With Git you have one repository for one project. Everyone working on the project needs to have the complete repository.

Revisions

With SVN it is very easy to refer to a repository state by a revision (a plain number). Git instead uses hash-codes which are hard to read and impossible to remember for humans.

Locking

When working frequently with binary files, SVN’s locking feature is a convenient way to exclusively reserve a certain file for editing for a while. Due to its distributed nature this is not possible with Git.

SmartSVN 6.0.5

We have released a new bug-fix release for SmartSVN 6. It contains following changes:

Fixed Bugs

  • Check Out: Possible internal error when closing frame during Check Out
  • Commit: Possible internal error when entering commit message
  • Edit Properties: Internal error (only Foundation version)
  • Output: Internal error when performing log on removed file
  • Refresh: Possible internal error
  • Setup/Check for Updates: Proxy does not work

Download SmartSVN 6.0.5

SmartSVN – Revision Graph with merge arrows

Displaying "merge arrows" in the Revision Graph is a feature which has been requested rather frequently since Subversion has introduced "merge tracking". This request comes mainly from (former) ClearCase users.

My personal expectations regarding this feature haven’t been too high. Rather, I was sure that it wouldn’t work well for Subversion but result in an overwhelming maze of merge arrows:
My concerns were that Subversion tracks its merge information by the svn:mergeinfo property which can grow rather complex. It inherits merge information from merge sources, can contain holes and so on.

Nevertheless, after doing some experiments it turned out that these concerns weren’t issues at all. Even for our most complex repository (which contains the shared code base of our products and primarily consists of merge revisions), results were looking promising, as the following screenshot shows:

SmartSVN Revision Graph with merge arrows

The only draw-back is that merge arrows require to scan the svn:mergeinfo for all displayed revisions in the Revision Graph. Currently, SVN provides no efficient way to perform such a query and hence the displaying may take some time.

Finally, we decided that merge arrows will be part of SmartSVN 6.1 and hope to get a first beta build out within the next few weeks.

False trojan alarm for SmartSVN Windows bundles confirmed

Starting today, AVG anti-virus scanner reports a couple of SmartSVN’s files on Windows as trojan (more details here).
We have just received following email from the AVG Customer Services which confirms the false positives and gives instructions on how to deal with them:


Unfortunately, the current virus database version may detect the mentioned virus on some legitimate applications. We can confirm that it is a false alarm. We would like to inform you that the false positive will be removed in the next Definitions update. Please update your AVG and if a new Definitions update was downloaded, check whether the file is still detected.


If you need to restore deleted files from AVG Virus Vault you can do it this way:

  • Open AVG user interface.
  • Choose “Virus Vault” option from the “History” menu.
  • Locate the file that was incorrectly removed and select it (one click).
  • Click on the “Restore” button.