Friday, 27 February 2009

Testing a class for making asynchronous calls

In my last post I looked at doing all kinds of evil things to get some legacy code under test. The code in question launched a new thread to do some work, and I ended up wrapping this asynchronous call in a ThreadDispatcher class for testing.

public class ThreadDispatcher {
  public AsyncCall Dispach(Action function) {
    var thread = new Thread(() => function());
    thread.Start();
    return new AsyncCall(thread);
  }
}

public class AsyncCall {
  private readonly Thread _thread;
  public AsyncCall(Thread thread) { _thread = thread; }
  public void WaitUntilCallFinishes() { _thread.Join(); }
}

I could then test the dispatcher like this:

[Test]
public void RunsFunctionFromDifferentThread() {
  var dispatcher = new ThreadDispatcher();
  int callingThreadId = Thread.CurrentThread.ManagedThreadId;
  int dispatchedThreadId = callingThreadId;
  var asyncCall = dispatcher.Dispach(() => dispatchedThreadId = Thread.CurrentThread.ManagedThreadId);
  asyncCall.WaitUntilCallFinishes();
  Assert.That(dispatchedThreadId, Is.Not.EqualTo(callingThreadId));
}

There's (at least) two problems with this. First, the return value of this function is a complete contrivance for the sake of testability (so our tests can call asyncCall.WaitUntilCallFinishes() before checking any assertions). This isn't always a bad thing, but in this case we are adding functionality and complexity that the production code does not need (the fact that the return value is always ignored in production code doesn't seem very reassuring). The second problem is that if we want to use the ThreadPool to run the work in the background then we don't get a reference to a Thread, and therefore can't wait on it.

A neater approach

This week I was faced with an actual need to do something like this (the previous implementation was an exercise stemming from a discussion with a mate). I ended up using similar TDD steps to come up with what I feel is a nicer way of testing a fire-and-forget asynchronous call. The implementation itself is trivial, and removes all traces of waiting on/joining threads:

public class AsynchronousDispatcher {
    public void Execute(Action action) {
        ThreadPool.QueueUserWorkItem(state => action());
    }
}

The fun part is the tests. Seeing as we've removed the concept of waiting from our implementation, this has to be handled from our tests instead. Which is fine, because the tests are the only place we need this functionality.

[Test]
public void ShouldExecuteAction() {
    var wasRun = false;
    DispatchToThreadAndWaitUntilDone(() => wasRun = true);
    Assert.That(wasRun, "Expected action to execute");
}

[Test]
public void ShouldExecuteActionOnDifferentThread() {
    var currentThreadID = Thread.CurrentThread.ManagedThreadId;
    var dispatchedThreadID = currentThreadID;

    DispatchToThreadAndWaitUntilDone(() => dispatchedThreadID = Thread.CurrentThread.ManagedThreadId);
    Assert.That(dispatchedThreadID, Is.Not.EqualTo(currentThreadID));
}

private void DispatchToThreadAndWaitUntilDone(Action action) {
    var resetEvent = new AutoResetEvent(false);
    var dispatcher = new AsynchronousDispatcher();
    dispatcher.Execute(() =>
                           {
                               action();
                               resetEvent.Set();
                           });
    resetEvent.WaitOne();
}

You'll see that the tests themselves are almost identical to the ones from last time, as most of the hard work is done in the DispatchToThreadAndWaitUntilDone(Action action) function. This uses an AutoResetEvent to handle synchronisation, and signals (resetEvent.Set()) as part of the work being done on our new thread. While the new thread is busy doing its asynchronous thang, the thread running our test uses WaitOne() to patiently sit around until it gets signaled that the asynchronous thread is done. We can then check that the results of the asynchronous operation matched what we expected, which for these tests is just that the code was run and that it used a different thread to run it.

So now we've got a trivial and tested implementation we can use to make asynchronous calls. If we extract an interface (or make Execute(...) virtual) we can easily mock this or replace it with a synchronous implementation to test classes that need to use AsynchronousDispatcher.

Apologies if this is all a bit simplistic, but I thought the tests looked kinda neat so I thought I'd share. Feel free to rip gigantic holes in it all. :)

Tuesday, 10 February 2009

Testing legacy code when simple threading's involved

A good friend and "former colleague in (an) archaic dev team" (his words :)) recently sent me a problem he was having testing some code he inherited. The code seemed to work during manual testing, but threw exceptions when being tested using NUnit under certain conditions. Let's look at a drastically modified example of the code:

[TestFixture]
public class BigImportantClassFixture {
  [Test]
  public void CanGetKnownEmployee() {
    var existingEmployeeId = Guid.Empty
    var importantClass = new BigImportantClass();
    var employee = importantClass.GetEmployee(existingEmployeeId);
    Assert.That(employee.Name, Is.EqualTo("Bilbo"));
  }
}

public class BigImportantClass {
  public Employee GetEmployee(Guid employeeID) {
    Employee employee = EmployeeRepository.GetEmployeeByID(employeeID);
    Logging.AsyncLog("Called GetEmployeeByID");
    return employee;
  }
}

public static class Logging {
  public static void AsyncLog(string message) {            
    var thread = new Thread(Log);
    thread.Start(message);
  }

  private static void Log(object message) {
    //Write line to log. This op may take some time
    Thread.Sleep(1000);
    Console.WriteLine(message);
  }
}

Can you guess the exception that cropped up? The unit test runner tears down the app domain it uses to run the fixtures when it is finished. Because the code spawns a new thread, this means that if that thread is still running it gets aborted as the app domain exits, so we get a ThreadAbortException. So how can we get this under test?

Questioning the approach

I think it would be remiss of us not to spend some time considering why we are using this approach. Is GetEmployee() called a lot and so needs to be fast? Will the added burden of spinning up another thread per call help, or will it hinder overall performance due to the increased load on the system? Would we be better off with a synchronous call? Do we even need logging here? Have we looked at using AOP for logging? Can libraries like log4net handle asynchronous logging for us? Or should we implement our own queue and have that serviced by threads that can work on processing the logs in batches? Should we be using background threads from the ThreadPool? Should we look at message queuing? Are static methods and opaque dependencies like this a work of pure evil? And if you were a tree, what tree would you be?

These are all good questions to ask and something my mate is looking into (I think he's leaning toward the larch). For the rest of this post however, I'd like to concentrate on how we could get this code under test. The code currently seems to work, but we don't have automated tests covering it, so we'll try and keep code changes small to give us confidence we aren't breaking anything during the process. This means we'll try and avoid changes ripping out the dependencies and using constructor injection. Once it's under test, we can worry about making it purdy and move on to more complex refactorings, and maybe even change the whole logging implementation once we decide which approach to use.

Isolating the logging behaviour in GetEmployee()

Our GetEmployee method does two things: looks up an Employee and does some logging. We already have the beginning of a test for the employee lookup part, but the coupling to the logging functionality is causing some problems. It is also untested. Let's write a test that isolates the behaviour.

[Test]
public void GetEmployeeCallIsLogged() {
  var mockLogger = MockRepository.GenerateMock<ILogger>();
  Logging.SetLogger(mockLogger);

  var importantClass = new BigImportantClass();
  importantClass.GetEmployee(Guid.Empty);

  mockLogger.AssertWasCalled(mock => mock.AsyncLog(Arg<String>.Is.Anything));
}

Normally I'd look at constructor injection for this sort of thing, but we're aiming for minimal modifications to the original code. Logging is also a bit of a special case — you potentially need it everywhere and so you may not want to explicitly put ILogger objects into every single object you have.

To pass this test, we'll need to extract an ILogger interface from our static Logger class, and change the implementation to use a Singleton approach (so we can override the behaviour by changing the instance).

public interface ILogger {
  void AsyncLog(string message);
}

public class Logging : ILogger {
  private static ILogger instance = new Logging();
  public static void SetLogger(ILogger logger) { instance = logger; }

  public static void AsyncLog(string message) {            
    instance.AsyncLog(message);
  }

  private static void Log(object message) {
    //Write line to log. This op may take some time
    Thread.Sleep(1000);
    Console.WriteLine(message);
  }

  void ILogger.AsyncLog(string message) {
    var thread = new Thread(Log);
    thread.Start(message);
  }
}

This passes our test. Notice we've made virtually no changes to the pre-existing code and only a few minor additions. We've added a singleton instance and a trivial SetLogger() method, and moved the code previously in the static AsyncLog() method into the ILogger.AsyncLog() instance method, with the static methods delegating to the instance one. We haven't had to change the GetEmployee() method at all. Hopefully this means we haven't broken anything. A quick manual test verifies that everything is working as before.

I'm a bit worried that we might replace the singleton instance with something evil during one test and inadvertently cause another test to break, but I guess that's a price of using singletons. At this point we just want to get the code under test before we go trying to make it all purdy. On the positive side, we can now test the employee lookup functionality independently of the logging, including testing that GetEmployee() invokes the logging call as required.

An integration test for logging

We've isolated our logging behaviour and tested it is called correctly from GetEmployee(), which means we can now write a test to make sure our logging works when it is called.

[TestFixture]
public class LoggingFixture {
  [Test]
  public void AsyncLogShouldDoFunkyLoggingStuff() {
    ILogger logging = new Logging();
    logging.AsyncLog("some message");
    Thread.Sleep(2000);
    //AssertDesiredSideEffectOccurred();
  }
}

Because of our previous efforts we can work directly with a Logging instance, rather than through the static methods. We still have a problem though. We want to check that whatever effect AsyncLog() has occurred properly, but because it is called asynchronously we have to put in a hacky Thread.Sleep() to make sure it is done. There are a few problems with this approach. Firstly, how do we know 2000 ms is enough? We might have our test intermittently breaking, which is a huge no-no. Secondly, it will make our tests run slow.

Isolating our threading problem

We'd really like the option of using Thread.Join() or similar so our test can wait on the asynchronous operation to finish. But we currently don't have any way to access the threading part of the operation.

One way to solve this problem is to implement the Asynchronous Programming Model. This lets the operation to be called asynchronously and waited on using polling/spin loop, call back or wait handle. Unfortunately it also looks like quite a lot of work, and a large amount of change to make without tests.

Another possible solution is to isolate the threading behaviour from the logging operation, just as we did for separating the employee lookup from the logging. Let's try that — we'll write a class that specialises in running a function in a new thread.

[TestFixture]
public class ThreadDispatcherFixture {
  [Test]
  public void CanRunFunctionCall() {
    var dispatcher = new ThreadDispatcher();
    bool wasRun = false;
    dispatcher.Dispach(() => wasRun = true);
    Assert.That(wasRun);
  }
}

public class ThreadDispatcher {
  public void Dispach(Action function) {
    function();
  }
}

This passes. Let's expand our test fixture, and try a naive implementation:

[Test]
public void RunsFunctionFromDifferentThread() {
  var dispatcher = new ThreadDispatcher();
  int callingThreadId = Thread.CurrentThread.ManagedThreadId;
  int dispatchedThreadId = -1;
  dispatcher.Dispach(() => dispatchedThreadId = Thread.CurrentThread.ManagedThreadId);
  Assert.That(dispatchedThreadId, Is.Not.EqualTo(callingThreadId));
}
//...
public class ThreadDispatcher {
  public void Dispach(Action function) {
    var thread = new Thread(() => function());
    thread.Start();
  }
}

This passes the new RunsFunctionFromDifferentThread() test, but luckily fails the original CanRunFuctionCall() test when run on my machine. I say luckily because it is timing dependent — the thread has not completed by the time the Assert.That(wasRun) executes. If you slip in a Thread.Sleep(...) for a few milliseconds you'll see both tests pass as the async thread starts to win our race condition.

This is a really good illustration that test coverage does not equal correctness, nor is it an excuse to avoid thinking :). Given we've thought about the problem though, TDD can help lead us to a solution. We need to make sure our async thread has run before we call our assert, so let's ammend our tests to show this:

[Test]
public void CanRunFunctionCall() {
  var dispatcher = new ThreadDispatcher();
  bool wasRun = false;            
  var dispatchedThread = dispatcher.Dispach(() => wasRun = true);
  dispatchedThread.Join();
  Assert.That(wasRun);
}
[Test]
public void RunsFunctionFromDifferentThread() {
  var dispatcher = new ThreadDispatcher();
  int callingThreadId = Thread.CurrentThread.ManagedThreadId;
  int dispatchedThreadId = callingThreadId;
  var dispatchedThread = dispatcher.Dispach(() => dispatchedThreadId = Thread.CurrentThread.ManagedThreadId);
  dispatchedThread.Join();
  Assert.That(dispatchedThreadId, Is.Not.EqualTo(callingThreadId));
}

And a reliably passing implementation (I hope):

public Thread Dispach(Action function) {
  var thread = new Thread(() => function());
  thread.Start();
  return thread;
}

It may not be a good idea to pass a reference to the Thread back, so it might be neater to wrap the Join() functionality in a new class (with tests updated accordingly).

public class ThreadDispatcher {
  public AsyncCall Dispach(Action function) {
    var thread = new Thread(() => function());
    thread.Start();
    return new AsyncCall(thread);
  }
}

public class AsyncCall {
  private readonly Thread _thread;
  public AsyncCall(Thread thread) { _thread = thread; }
  public void WaitUntilCallFinishes() { _thread.Join(); }
}

This is all new code, so we shouldn't have broken anything that was working in our original implementation.

Bringing logging and threading back together

Now we've separated logging and threading, we need to bring them back together so this thing actually works as required. Let's jump into our LoggingFixture:

[TestFixture]
public class LoggingFixture {
  [Test]
  public void AsyncLogShouldDoFunkyLoggingStuff() {
    ILogger logging = new Logging(new ThreadDispatcher());
    logging.AsyncLog("some message");
    Thread.Sleep(2000);
    //AssertDesiredSideEffectOccurred();
  }

  [Test]
  public void AsyncLogShouldUseThreadDispatcher() {
    var dispatcher = MockRepository.GenerateMock<ThreadDispatcher>();
    ILogger logging = new Logging(dispatcher);
    logging.AsyncLog("some message");
    dispatcher.AssertWasCalled(x => x.Dispach(null), options => options.IgnoreArguments());
  }
}

public class Logging : ILogger {
  private readonly ThreadDispatcher dispatcher;
  private static ILogger instance = new Logging(new ThreadDispatcher());

  public Logging(ThreadDispatcher dispatcher) { this.dispatcher = dispatcher; }

  public static void SetLogger(ILogger logger) { instance = logger; }

  public static void AsyncLog(string message) {            
    instance.AsyncLog(message);
  }

  private static void Log(object message) {
    //Write line to log. This op may take some time
    Thread.Sleep(1000);
    Console.WriteLine(message);
  }

  void ILogger.AsyncLog(string message) {
    dispatcher.Dispach(() => Log(message));
  }
}

This has probably been the most radical change to our code. We've changed the implementation of AsyncLog to delegate the threading to our new ThreadDispatcher. We've also added some dependency injection, using the Logging constructor to pass in our ThreadDispatcher. Everything is green. Even better, we can now update the original AsyncLogShouldDoFunkyLoggingStuff() and test the logging behaviour in isolation.

[TestFixture]
public class LoggingFixture {
  private class FakeThreadDispatcher : ThreadDispatcher {
    public override AsyncCall Dispach(Action function) {
      function();
      return new AsyncCall(null);
    }
  }
  [Test]
  public void AsyncLogShouldDoFunkyLoggingStuff() {
    ILogger logging = new Logging(new FakeThreadDispatcher());
    logging.AsyncLog("some message");
    //No more Thread.Sleep(...) here. Our FakeThreadDispatcher will do a synchronous call.
    //AssertDesiredSideEffectOccurred();
  }
  //...
}

You could also do some fancy mockFu for this, but in this case I think it's easier to hand code a FakeThreadDispatcher (if changes to the base class cascade down to our fake and it starts getting painful we can switch a generated mock or stub).

Conclusion

Our Logging implementation only calls Console.WriteLine(), so for our AssertDesiredSideEffectOccurred() we would need to fake that out. We won't go that far down the rabbit hole though, as the real logging implementation would be probably do all kinds of exciting things that we could test. The point is that we can now test the logging in isolation from our threading. Our threading code is also tested, and we can test our original employee look up too (by setting a stub ILogger when testing BigImportantClass).

Best of all, the only really changes of any consequence we made to our original code is implementing a singleton Logging instance and extracting the thread launching code to a new class. So, from a unit testing point of view, we have gained a lot for very little risk.

This was a very simple bunch of refactorings to perform. I hope that came across during the post, but sometimes these things don't translate well to post format. If that's the case then try picking up the code from the start of this post and go through the process of getting it under test.

As always feel free to pick holes in this post and let me know via comment or email. Hope this helps!

Wednesday, 4 February 2009

Git-aware PowerShell prompt

Today a colleague sent around an interesting link on how to put your git status in your bash prompt. I thought I'd spend a few minutes trying to get a similar effect in PowerShell (v2 CTP3). It's not particularly useful, but I found it an interesting exercise. Here's what I came up with, saved in GitAwarePrompt.ps1. Disclaimer: I know nothing about PowerShell so use anything from this post at your own risk. :)

function Get-GitBranchNameWithStatusIndicator {
  $statusOutput = Invoke-Expression 'git status 2>$null'  #1
  if (!$statusOutput) { return } #2
  $branch = $statusOutput[0] #3
  if ($branch -eq "# Not currently on any branch.") {
    $branch = "No branch"
  } else {
    $branch =  $branch.SubString("# On branch ".Length) 
  }
  $statusSummary = $statusOutput[-1] #4
  if ($statusSummary -eq "nothing to commit (working directory clean)") { #5
    $statusIndicator = "" 
  } else {
    $statusIndicator = "*"
  }
  return $branch + $statusIndicator
}

function prompt { #6
  $gitStatus = Get-GitBranchNameWithStatusIndicator
  Write-Host ("PS " + $(get-location)) -nonewline
  if ($gitStatus) {
    Write-Host (" [" + $gitStatus +"]") -nonewline -foregroundcolor Gray
  }
  Write-Host (">") -nonewline
  return " "
}

I've put some numbered comments on a couple of lines so we can go through the main parts of the script, or you can skip to the next heading if you just want to try out the script.

Line #1 uses the Invoke-Expression commandlet to run the git status command and store the output in the local $statusOutput variable. We are using 2>$null to drop any output written to standard error, otherwise whenever we try and write a prompt in a non-git directory we'll get a git error message appearing. You'll also notice we have the git status 2>$null command surrounded by single quotes ('), rather than double quotes ("). The reason is that PowerShell automatically performs variable substitution within double quoted strings. So if we used double quotes the $null would be replaced by with nothing (it's current value), which will cause us no end of problems (go on, ask me how I know! :)).

If the git status command errors out (say, if the current directory is not in a git repo), then $gitStatus will be null. Line #2 checks for this and returns void if $statusOutput is undefined. Otherwise $statusOutput will an array of objects, with an item for each line of the command output. Line #3 grabs the first line of output, which contains a string which contains our branch name, and stores it in a variable. The if/else that follow checks first to make sure we are actually on a branch, and parses the branch name from the line.

Line #4 was a nice surprise for me -- PowerShell supports wrapped array indexing! Using an index of -1 grabs the last item in the array. Very pythonesque :). Line #5 then compares this with the output git status gives when there are no changes, and the rest of the if/else block sets the $statusIndicator based on this result. (No built in ternary operator apparently.)

Finally, line #6 defines a prompt function, which PowerShell uses to write it's prompt.

Using the script

If we just run this script from within PowerShell it will do absolutely nothing. The reason is because any functions or variables defined will be cleaned up when the script exits. To change the scope and affect the current environment we need to dot-source the script, like this (depending on where you saved the script):

PS > . $HOME/Documents/WindowsPowerShell/GitAwarePrompt.ps1

Without the dot and space, you get nothing. With the dot-sourced script, we have created a prompt function for PowerShell to call, and we get the status of our Git working directory from our command line:

PS C:\Development\git\HelloWorld [helloGit]> "Modify hello.txt" > hello.txt
PS C:\Development\git\HelloWorld [helloGit*]> git commit -a -m "Commit change"
[helloGit]: created 8a7947c: "Commit change"
 1 files changed, 0 insertions(+), 0 deletions(-)
PS C:\Development\git\HelloWorld [helloGit]> git checkout master
Switched to branch "master"
PS C:\Development\git\HelloWorld [master]> "Change hello.txt again" > hello.txt
PS C:\Development\git\HelloWorld [master*]>
PS C:\Development\git\HelloWorld [master*]> cd ..
PS C:\Development\Git>

Setting the default prompt

You can also more permanently modify your PowerShell prompt by putting the script in your PowerShell profile, which is set to something like ~\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 by default (if it doesn't exist, you can create it from PowerShell using New-Item $PROFILE -ItemType file -Force). This can be something like the Git-aware prompt shown here, or something more interesting. Be careful you don't slow down your shell too much though: prompt is obviously called on every new line!

Tuesday, 3 February 2009

Setting up diff and merge tools for Git on Windows

UPDATE!!! I'm now using an easier way of configuring diff and merge tools. If you don't mind using KDiff3 then you might want to check that out first. If you want flexibility in which tools you use and how they're used, then read on. -- DT, 26 Mar 2010

I finally got tired of reading diff outputs from git on the command line, and decided to hook up a visual diff and merge tool. After piecing together hints from various posts around ye olde intraweb I've now got somethings that works. I am using Git on MSys to get Git working on Windows via a PowerShell command line, but a similar setup might work via Cygwin or via the cmd.exe command line.

Setting up a diff tool

Update 2009-05-20: This approach stopped working for me when I upgraded to Windows 7 and Git 1.6.3. I had to switch to using git difftool instead.

The easiest way I found to do this was to create a shell script wrapper for your diff tool of choice. To make things easy on me I put the script, git-diff-wrapper.sh in C:\Program Files\Git\cmd, which is in my Path environment variable. The file contents looks like this:

#!/bin/sh

# diff is called by git with 7 parameters:
#  path old-file old-hex old-mode new-file new-hex new-mode
"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$2" "$5" | cat

#"C:/Program Files/WinMerge/WinMergeU.exe" "$2" "$5" | cat
#"C:/Program Files/KDiff3/kdiff3.exe" "$2" "$5" | cat

The basic format of this is stolen directly from this post on the Msysgit site. Provided your diff tool can be called from the command line, you'll be able to set it up to work with Git using this template. In this case I've used it to setup a call to Sourcefear's DiffMerge, a nice free (as in beer) diff and merge tool.

You'll also see I've commented out calls to WinMerge and KDiff3, which are both free as in beer and speech. I ended up settling on DiffMerge because it is purdy (unlike KDiff3 -- sorry), and also does 3-way merges (unlike WinMerge, which was my previous diff tool of choice).

The next step is telling Git about your wrapper. In your home directory (C:\Users\(username) or the corresponding Documents and Settings equivalent) Git will normally have created a .gitconfig file. If not then go ahead and create one. You'll need to have the following section in there:

[diff]
 external = C:/Program Files/git/cmd/git-diff-wrapper.sh

We can now use git diff and it will fire up our diff tool of choice.

Setting up a merge tool

I had more trouble getting a merge tool working, largely because putting references to paths like C:/Program Files/... in .gitconfig seems to bork when used here. Again I ended up using the wrapper approach, creating git-merge-diffmerge-wrapper.sh at C:\Program Files\Git\cmd to call DiffMerge. This file ended up looking like this:

#!/bin/sh

# Passing the following parameters to mergetool:
#  local base remote merge_result

"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$1" "$2" "$3" --result="$4" --title1="Mine" --title2="Merging to: $4" --title3="Theirs"

I unashamedly stole this from Alexander Groß's post on getting DiffMerge running on Cygwin-based Git (with slight modifications, any faults are mine :)). We can then wire this up in .gitconfig again:

[merge]
    tool = diffmerge

[mergetool "diffmerge"]
 cmd = git-merge-diffmerge-wrapper.sh "$PWD/$LOCAL" "$PWD/$BASE" "$PWD/$REMOTE" "$PWD/$MERGED" 
    trustExitCode = false
 keepBackup = false
 
[mergetool "kdiff3"]
    path = C:/Program Files/KDiff3/kdiff3.exe
    keepBackup = false
    trustExitCode = false

Now remember that C:\Program Files\Git\cmd is on my PATH, so I can set the command to call git-merge-diffmerge-wrapper.sh without fully qualifying the path. The details on the arguments are available from the git-mergetool(1) man page. I've also left in a KDiff3 version that seems to work too (Git has some built in support for KDiff3 I think, which is why you can get away with only specifying the path).

Time for a test drive

Let's make sure everything's in working order. I'll open up a PowerShell window and let's see how we go (you'll have to excuse me for using old DOS commands instead of fancy PowerShell ones, I've only just switched to PS after running into various issues with the cmd.exe command line).

PS> mkdir HelloWorld
PS> cd HelloWorld
PS> git init
  Initialized empty Git repository in C:/Development/Git/HelloWorld/.git/
PS> echo Hello World! > hello.txt
PS> git add hello.txt
PS> git commit -m "Initial commit"
  [master (root-commit)]: created 2a2cf34: "Initial commit"
   1 files changed, 0 insertions(+), 0 deletions(-)
   create mode 100644 hello.txt
PS> git checkout -b helloGit
  Switched to a new branch "helloGit"
PS> echo Hello Git! > hello.txt
PS> git add hello.txt
PS> git commit -m "Update from helloGit branch"
  [helloGit]: created e71437b: "Update from helloGit branch"
   1 files changed, 0 insertions(+), 0 deletions(-)
PS> git checkout master
  Switched to branch "master"
PS> echo Hello World! Hello indeed! > hello.txt
PS> git add hello.txt
PS> git commit -m "Update from master"
  [master]: created 5dee19d: "Update from master"
   1 files changed, 0 insertions(+), 0 deletions(-)
PS> git merge helloGit
  warning: Cannot merge binary files: HEAD:hello.txt vs. helloGit:hello.txt

  Auto-merging hello.txt
  CONFLICT (content): Merge conflict in hello.txt
  Automatic merge failed; fix conflicts and then commit the result.
Because I've used echo to stream data into hello.txt the files have ended up in binary mode. Let's ignore that as it is just to get an easy demo going. The important thing is we now have a merge conflict to resolve.

If we now type in git mergetool Git ask's us if we'd like to run our merge tool. We can hit enter and up pops DiffMerge. If you wanted KDiff3, we could have called git mergetool -t kdiff3, or any other merge tool in our .gitconfig (by default the tool specified in the merge.tool config option is used).

PS> git mergetool
Merging the files: hello.txt

Normal merge conflict for 'hello.txt':
  {local}: modified
  {remote}: modified
Hit return to start merge resolution tool (diffmerge):

Resolve the merge conflict however you like and then try this:

PS> echo Wow, it worked! > hello.txt
PS> git diff

Hooray, we have our diff tool working! We can also run commands like git diff HEAD~ HEAD and git diff helloGit master and get the output via our diff tool.

Conclusion

This setup earns the coveted Works on My Machine certification, but even if that's the only place it works then hopefully it still gives you enough information to configure your Windows diff and merge tools for use with Git.

If you hunt down the relevant command line options you should be able to get pretty much any tool working: Beyond Compare, p4merge, TortoiseMerge etc.

Hope this helps.