Skip to content

Instantly share code, notes, and snippets.

@aschweer
Created February 14, 2016 20:14
Show Gist options
  • Save aschweer/6e63f69b263c5c78ac57 to your computer and use it in GitHub Desktop.
Save aschweer/6e63f69b263c5c78ac57 to your computer and use it in GitHub Desktop.
git pre-commit hook to check XML files for well-formedness, using 'file' and 'xmllint' commands
#!/bin/bash
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments. The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".
if git rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
check_xml_wellformed()
{
for FILE in `git diff-index --name-only --cached $against -- ` ; do
mimetype=`file --brief --mime-type $FILE`
# if file is an xml file, check that it is well-formed
if [ $mimetype == 'application/xml' ]; then
if ! xmllint --noout $FILE; then
echo "========================================================="
echo "Unstaging $FILE for the commit -- XML but not well-formed"
git reset -q HEAD $FILE
retval=1
else
echo "XML check for $FILE: OK"
fi
fi
done
if [[ $retval -gt 0 ]]; then
exit $retval
fi
}
check_xml_wellformed
@aschweer
Copy link
Author

On an ubuntu system, you need these packages:

  • libxml2-utils to get the xmllint command;
  • findutils to get the find command.

Put the pre-commit file into a project's .git/hooks directory to have it run every time you stage a file for commit. You can also put it into your global git template dir to have it applied to all git projects you create from then onwards

@aschweer
Copy link
Author

A quick note -- it's using slightly more advanced mimetype detection than just going by extension, mainly because I often work on a project with lots of XML files that don't have .xml extensions and I didn't want to hard-code the list of extensions used there.

@robilic
Copy link

robilic commented Apr 25, 2022

I have found that you can sneak a file past this if you have the .xml extension but have it not be a valid XML file. The mime-type check fails so xmllint never runs.

$ cat bad-xml.xml
<xml>
Some text
<a>foobar</b>
</>
$ file --brief --mime-type bad-xml.xml
text/plain

Version that uses a file extension check rather than mime-type

https://gist.github.com/robilic/e86313fcb3ff7f763b43c43a43f508a0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment