How to handle xml/html in git feature branch workflow? How to handle xml/html in git feature branch workflow? xml xml

How to handle xml/html in git feature branch workflow?


Git allows for custom merge drivers, selected via gitattributes per path (e.g. for all *.xml files).

What you need to find is a XML-aware merge driver, plus possibly also write a simple script to transform between Git conventions and said merge driver conventions. There is for example XML::Merge Perl module. There is XyDiff, but it looks like it lacks three-way merge (and I guess that for XML building 3-way merge from diffs like described in A Formal Investigation of Diff3 paper (PDF) wouldn't work). You can also read Matching, diffing and merging XML blog post (or article referenced therein).

Another solution would be to unset merge attribute for XML files (they would be treated like binary files wrt. merge conflicts), and use some graphical merge tool to resolve merge conflicts, perhaps via git mergetool.


If you know you could automate some of the merge issue you are having with those merges of xml files, you could script those resolutions.
If there is script, you can call them from a merge driver tailored for xml/xhtml files, only in some directories.

See here for a (really simple) of a merge driver.

That way, any conflict which remains (because the merge driver script did not solve it) are legitimate merge issues that need to be addressed.


There was an item noted in comments in another question that now redirects here (How to setup git merge / git pull for xml files?). Logically, this too should be a comment, but it really needs formatting. So, here it is as an answer, with this subject:

Setting merge.conflictStyle to diff3 can be helpful

Doing:

git config --global merge.conflictStyle diff3

(or the same without --global if you want it just for one repository, but I prefer the --global myself) can make the work-tree copy more useful. Note that if you are writing a merge driver, you do not get the work-tree copy as an input. Instead, you get the three files, ours base and theirs, as your three inputs. This is primarily useful if you aren't trying to write your own merge driver (and writing your own is tricky: if it were easy, XML merge would have been solved quite a while ago).

Example

Here are the example inputs from the other posting:

$ cat base<li>  <span>BA</span></li>$ cat ours<li>  <span>BA</span></li><li>  <span>CE</span></li>$ cat theirs<li>  <span>BA</span></li><li>  <span>DF</span></li>

We can now see how Git will merge these files, using git merge-file, which is the command line equivalent of one low-level (file-level) operation from a git merge:

$ cp ours current$ git merge-file current base theirs$ cat current<li>  <span>BA</span></li><li><<<<<<< curr  <span>CE</span>=======  <span>DF</span>>>>>>>> theirs</li>

Here, as you can see, Git has pointed out that the changes in ours (copied to current) conflict with the changes in theirs as compared to base. However, some parts of the conflict were easy to resolve, so Git did that, and marked only the remaining parts of the conflict.

When we request a diff3 style merge, however, we get this:

$ cp ours current$ git merge --diff3 current base theirs$ cat current<li>  <span>BA</span></li><<<<<<< curr<li>  <span>CE</span></li>||||||| base=======<li>  <span>DF</span></li>>>>>>>> theirs

There are two differences. Not only does Git add the ||||||| base section—which in this case, is empty; there are no lines in the merge base input—but it also stops doing a partial resolution of the changes in ours / current with those in theirs.

(This is necessary since Git now has to show "ours vs base" and "theirs vs base" rather than just "ours vs theirs, after best effort".)