Comparing a local file with a workspace file with C# and TFS

The situation is simple:

  • we need to send messages to another system
  • the developers of the other system need documentation on the layout of these messages
  • this is a company-specific protocol (no JSON or anything standard, because we're talking to old Fortran machines here)
  • naturally, the documentation is made in Word filesTaking an example from a session I saw at ngEurope, I decided we might be better off auto-generating this documentation. Keeping Word files in sync with the evolving code is a tedious, manual process, not to mention that the Word files are never in sync 10 years down the road.

And as the code is the single point of truth, I started on automating the process. I hate repeating manual things. It's boring, allows for manual error (I remember updating a production SQL database instead of the beta database!), and needs to be taught to newcomers time and again.


After having written code to generate the documentation (too specific to put here), I needed a way of having the build automatically add the new file to the pending changes, or if nothing had changed, undo the checkout (sadly, I'm on TFS; git would not have this problem).

So this is how you can compare a local file with the server version of the file:

private bool HasFileChanged(string file, TfsTeamProjectCollection server, Workspace workspace)  
    string diff;

    var versionControlServer = server.GetService<VersionControlServer>();

    var serverPath = workspace.GetServerItemForLocalItem(file);
    var serverVersion = new DiffItemVersionedFile(versionControlServer, serverPath, VersionSpec.Latest);
    var localVersion = new DiffItemLocalFile(file, Encoding.UTF8.CodePage, DateTime.Now, false);

    using (var stream = new MemoryStream())
    using (var writer = new StreamWriter(stream))
        var diffOptions = new DiffOptions
            Flags = DiffOptionFlags.EnablePreambleHandling,
            OutputType = DiffOutputType.Unified,
            TargetEncoding = Encoding.UTF8,
            SourceEncoding = Encoding.UTF8,
            StreamWriter = writer

        Difference.DiffFiles(versionControlServer, serverVersion, localVersion, diffOptions, serverPath, true);

        diff = Encoding.UTF8.GetString(stream.ToArray());

    return diff != "";
The server and workspace variables can be made like this:
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(file);  
var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri);  
var workspace = workspaceInfo.GetWorkspace(server);