Is there an way that you can run clang-format
in a mode where it reports if the file meets the specified format? A kind of dry-run mode where it reports if a change is needed, but doesn't make the change. Ideally I'd like clang-format to just return a non-zero exit code if the file needs changes. Or, even more ideally, a non-zero exit code and a list of the files that need changes on standard output.
I'm trying to keep the question generic, so that more people can answer, but what I am trying to do is write a git pre-commit hook that will reject any commits that don't match the expected .clang-format . It's easy to run clang-format on the list of files in the index. But it's hard to know if clang-format actually changed anything.
I have one potential solution based on -output-replacements-xml
(that I will post as an answer), but it's a hack and I feel like this should be more straightforward. Comments/suggestions, edits, different answers/approaches are all welcome.
One of the reasons I feel like this should be easier than it is because -output-replacements-xml essentially gives me the answer that I want, it just doesn't give it to me in an easy to consume way. However, since the output if no replacements are needed is very predictable, parsing the output isn't too hard.
What I have right now is
clang-format -style=file -output-replacements-xml | grep -c "<replacement " >/dev/null
This actually returns the inverse of the exit code I want, since grep returns 0 if something matches, 1 if nothing does. But that is easy enough to deal with.
So the relevant bit of my git pre-commit hook would be
git diff --cached --name-only --diff-filter=ACMRT |
grep "\.[cmh]$" |
xargs -n1 clang-format -style=file -output-replacements-xml |
grep "<replacement " >/dev/null
if [ $? -ne 1 ]; then
echo "Commit did not match clang-format"
exit 1
fi