Re: Server-side preventing some files from being overwritten
From: Ævar Arnfjörð Bjarmason <hidden>
Date: 2016-07-15 14:03:02
On Thu, Jul 14, 2016 at 8:44 PM, Junio C Hamano [off-list ref] wrote:
On Thu, Jul 14, 2016 at 11:27 AM, Junio C Hamano [off-list ref] wrote:quoted
Thorsten Glaser [off-list ref] writes:quoted
if test x"0" != x"$(comm -23z \ <(git ls-tree -r -z "$old" "$subdir" | sort -z) \ <(git ls-tree -r -z "$new" "$subdir" | sort -z) | wc -c)"; then echo >&2 'Untouchable files touched, commit rejected!' exit 1 fiCan't this become simpler, e.g. if ! git diff-tree --quiet "$old" "$new" -- "$subdir" then echo >&2 "Ooh, $subdir is touched" exit 1 fiEhh, you need to tell diff-tree to recurse, i.e. "diff-tree -r".
Note that although this is literally what Thorsten is asking for, I think it's worth noting for the list explicitly that all these examples that do "diff $old..$new" will *not* prevent your repository from having *commits* that touch those files, but they will prevent you from having *pushes* where the end state is a net change in those files. I.e. it allows pushing a series which is a series of two commits which: 1. Change the forbidden file(s) 2. Undo changes to the forbidden file(s) This *can* be critically important or not matter at all depending on your use case, i.e. does it matter that disallowed and potentially malicious changes come up in "git bisect", or will you ever be rolling out anything but the latest tip of the branch you're testing in production? If the answer to either of those is "yes" you need something that does a "git log --stat $old..$new" and parses out if *any* of the commits make changes to those files. See e.g. my https://github.com/avar/pre-receive-reject-binaries for one example of that, although it rejects binaries you could easily modify it to check the filename(s) instead.