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 mutandis, ceteris 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:
- Press Cancel on the dialog box
- Access the KDiff3 settings by clicking Settings > Configure KDiff3…
- Click on the Diff tab
- Enter
C:\gitfiles\xslt.cmd c:\gitfiles\sort-dbml.xslt
into the Preprocessor command text box - 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.