Skip to content

Merge your DBML

There is always better way to merge your DBML files when somehow your DBML become disorganized. Luckily KDiff3 has a feature that allows you to rearrange the lines in all the versions of a file that are involved in the 3-way merge. This will allow KDiff3 to compare lines that were meant to be compared together instead of getting all confused. I will show you how we did it using Git for a particular xml file type of file that was giving us problems. In our case, we were having problems with dbml files that are part and parcel of Linq to SQL. And it wasn’t our favourite colleague that was causing us issues – it was Visual Studio! This is Visual Studio will save content of the dbml file in a random order whenever we make changes to that file.

I will show you how we solved this problem using a XML transform and KDiff3’s pre-processor feature. If you are interested in using this technique for file types that are not XML based, then you will need to substitute the XML transform for another formatting and arrangement technique or tool, mutatis mutandisceteris parabis , et cetera.

Ready? Here we go!

What you will need

Windows

This guide uses Windows tools, though some of them are cross platform. If you’re on a Mac or Linux, then you can substitute these lame Windows tools for your awesome tools, but that is an exercise for the reader, as they say.

KDiff3

We will be using KDiff3’s pre-processor feature to hook in the sorting the base, local and remote versions of the dbml file. KDiff3 ships with some git installations, otherwise it can be found at KDiff3 or it can be installed using Chocolatey by running cinst kdiff3 from the command line.

XMLStarlet

XmlStarlet is used to do the xml transform. It can be downloaded from XMLStarlet or installed using Chocolatey by running cinst xmlstarlet from the command line.

Git

Git has some very powerful configuration options for specifying merge tools. More specifically, different tools can be specified depending on the file type that you want to merge. Subversion can do this too. Maybe your version control of choice can, but again this is an exercise for the reader.

Setup

To set up the merging of dbml files, you will need to complete the following steps:

  • Create the sorting XSLT file
  • Create a batch file that invokes the XML transform
  • Create a KDiff3 configuration file that invokes the batch file as a pre-processor instruction
  • Configure git to use KDiff3 for dbml files

Step 1: Create the sorting XSLT file

Create a file called sort-dbml.xslt in C:\gitfiles (or another location of your choosing) and paste the following code in as content:

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="http://schemas.microsoft.com/linqtosql/dbml/2007">  
    <xsl:output encoding="utf-8" />

    <xsl:template match="comment()" priority="2">
    </xsl:template>

    <xsl:template match="/| @* | node()" priority="1">
        <xsl:copy>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="a:Database" priority="2">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates select="a:Connection" />
            <xsl:apply-templates select="node()[not(a:Connection)]">
                <xsl:sort select="@Name" />
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:transform>  

Step 2: Create a batch file that invokes the xml transform

Create a files called xslt.cmd in C:\gitfiles and paste the following code in as content. The code below assumes that xml.cmd or xml.exe is in your path, so if it isn’t, then you will need to change the content to reference the full path.

@echo off
xml.exe tr %1 | xml.exe fo  

If you installed XmlStarlet using Chocolatey, then XmlStarlet will probably be executed via a batch file. In this case, xslt.cmd will need to look like this:

@echo off
call xml tr %1 | call xml fo  

Step 3: Create a KDiff3 configuration file that includes the pre-processor instruction

Start up a command line and execute the following commands:

> C:
> cd \gitfiles
> kdiff3 --config dbml.kdiffrc

This will launch KDiff3 and create a new configuration file called dbml.kdiffrc. Now:

  1. Press Cancel on the dialog box
  2. Access the KDiff3 settings by clicking Settings > Configure KDiff3…
  3. Click on the Diff tab
  4. Enter C:\gitfiles\xslt.cmd c:\gitfiles\sort-dbml.xslt into the Preprocessor command text box
  5. Click Ok and exit Kdiff3

Step 4: Configure git

Add the following section to your git config (this is a file called .gitconfig in your home directory):

[mergetool "dbml"]
    cmd = \"C:/Program Files/KDiff3/KDiff3.exe\" ­­config \"C:/gitfiles/dbml.kdiffrc\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" ­o \"$MERGED\"
    keepBackup = false
    trustExitCode = false

Then in all your git repositories, make sure that this line forms part of your .gitattributes file (or .git\info\attributes if you don’t want to commit this configuration:

*.dbml diff=dbml

You’re all set up now. Next time you run a git mergetool command that involves a dbml file, KDiff3 will sort the file before presenting the conflicts to you.

You may also like...