My situation is (roughly analogous to) the following:
We have the directory structure
my-repo/
input.txt
output-1.bin
output-2.bin
output-3.bin
converter.py
For simplicity, let's say that converter.py
looks like this:
#/usr/bin/env python
from shutil import copyfile
copyfile('input.txt', 'output-1.bin')
copyfile('input.txt', 'output-2.bin')
copyfile('input.txt', 'output-3.bin')
We version-control both input.txt
and output-*.bin
. I know, I know, you're going to say that there's no reason to version-control the generated files... but this is non-negotiable in our case. We use the .bin files a lot, they're mission-critical, and we can't risk a subtle bug in converter.py
screwing them up. Version-controlling both the converter.py
script and the outputs makes sure that the ramifications of any script change are super obvious in the git history.
But this leads us to a problem. We can modify input.txt
and commit that diff without ever running converter.py
to update the .bins!
This is a perfect job for a git pre-commit hook.
We can get the list of changed files via git diff --cached --name-only --diff-filter=ACM
. If that list includes input.txt
or converter.py
, then we want to run converter.py
and then diff the output against the .bin files being committed.
So I have two problems/questions:
How can I run
converter.py
from within the pre-commit hook, without clobbering whatever uncommitted changes the user might have in his local checkout? This is basically How do I properly git stash/pop in pre-commit hooks to get a clean working tree for tests?How can I then, after running
converter.py
, ask git "Are there now any uncommitted diffs in the working tree?" I mean I hope the answer is simplygit diff
, but I'm unsure what exactlygit diff
means when executed from inside a pre-commit hook.
The reason this problem is non-trivial is that converter.py
mutates the state of the working tree, instead of just spitting its output to stdout. Sadly this, too, is a non-negotiable axiom of the problem.
Thoughts? Working code snippets? :)