Dirstate.update_by_delta was using os.path.join() to handle the 'new path' for renames. Which meant that on Windows the rename of 'a/b' => 'c/d' would show as a rename of 'a/b' => 'c/d' (the reverse of 'c/d <= 'a/b' was correct though...)
The simple fix is to just use osutils.pathjoin() in both places.