What is the best approach to write hooks for Subversion in Windows? As far as I know, only executable files can be used. So what is the best choice?

  • Plain batch files (very limited but perhaps OK for very simple solutions)
  • Dedicated compiled executable applications (sledgehammer to crack a nutshell?)
  • Some other hybrid choice (like a batch file running a Powershell script)

Depending on the complexity, each situation is different, If I am just simply moving files around, I'll write a quick batch file. If I want to do something more complex Ill normally just skip the scripting part and write a quick c# program that can handle it.

The question then is do you put that c# program in svn and have it versioned :)

edit: The benefits of a dedicated c# application is that I can reuse code fragments to create new hooks later, including a simple log output I created to handle hook logging.


I've written hooks in Python on Windows since there are a lot of examples on the net (usually for Linux but the differences are small). We also use Trac integrated with SVN and there is a Trac API accessible via Python which lets us automatically create/modify Trac tickets from SVN hook scripts.

Sean Carpenter
+5  A: 

Take a look at Subversion Notify for Windows


+1  A: 

Check CaptainHook, "a simple plugin framework for writing Subversion hooks using .NET".

Sören Kuklau
+3  A: 

We've got complex requirements like:

  1. Only certain users can create folders in parts of the SVN tree, but everyone can edit files there
  2. Certain file extensions cannot contain certain text in the file
  3. Certain file extensions can only be stored in a subset of directories
  4. As well as several simpler ones like, Must have a commit comment
  5. Regression testable by running new hook against all previous SVN commits

#5 is huge for us, there's no better way to know you're not gonna break commits moving forward than to be able to push all previous commits through your new hook. Making the hook understand that 1234 was a revision and 1234-1 was a transaction and making the appropriate argument changes when calling svnlook, etc. was the best decision we made during the process.

For us the nut got big enough that a fully unit testable, regression testable, C# console exe made the most sense. We have config files that feed the directory restrictions, parse the existing httpd_authz file to get "privileged" users, etc. Had we not been running on Windows with a .NET development work force, I would have probably written it all in Python, but since others might need to support it in the future I went .NET over .BAT, .VBS, Powershell silliness.

Personally I think Powershell is different enough from .NET to be mostly useless as a "scripting" language. It's good if the only cmd line support for a product comes via PS (Exchange, Windows 2k8), etc. but if all you want to do is parse some text or access regular .NET objects PS just adds a crazy syntax and stupid Security Iron Curtain to what could be a quick and easy little .NET app.

+3  A: 

I’ve just spent several days procrastinating about exactly this question. There are third party products available and plenty of PERL and Python scripts but I wanted something simple and a language I was familiar with so ended up just writing hooks in a C# console app. It’s very straight forward:

public void Main(string[] args)
  string repositories = args[0];
  string transaction = args[1];

  var processStartInfo = new ProcessStartInfo
                             FileName = "svnlook.exe",
                             UseShellExecute = false,
                             CreateNoWindow = true,
                             RedirectStandardOutput = true,
                             RedirectStandardError = true,
                             Arguments = String.Format("log -t \"{0}\" \"{1}\"", transaction, repositories)

  var p = Process.Start(processStartInfo);
  var s = p.StandardOutput.ReadToEnd();

  if (s == string.Empty)
    Console.Error.WriteLine("Message must be provided");


You can then invoke this on pre commit by adding a pre-commit.cmd file to the hooks folder of the repo with the following line:

[path]\PreCommit.exe %1 %2

You may consider this overkill but ultimately it’s only a few minutes of coding. What’s more, you get the advantage of the .NET language suite which IMHO is far preferable to the alternatives. I’ll expand my hooks out significantly and write appropriate tests against them as well – bit hard to do this with a DOS batch file!

BTW, the code has been adapted from this post.

Troy Hunt

If you have a php executable with a help of simple php class you may write hook script in php like it is shown here http://www.devhands.com/2010/01/subversion-hook-php-framework-in/