简体   繁体   中英

Git pre-commit hook to check number of files changing

Our repository has custom status checks that get fired based on the number of files that we changed. If the number of files changed in a single PR is large, these status checks can bring down a downstream dependency. (there are requests to a service being made in these status checks). I'm not here to argue about these status checks and why they are there in the first place, at this point in time we can't change that or scale the service to handle such load.

The idea to gate these large changes is to add a git hook on pre-commit which basically gets the number of files that are different between the current branch and the tip of remote master. Then we want to error out if the number of those files is greater than a certain number.

Basically the way I'm going about this is by using the following commands in a git hook


# Refresh local reference to origin/HEAD
git fetch

# Get the diff between the tip of current branch and the tip of origin/HEAD and count them
git diff --name-only --cached origin/HEAD | wc -l

... 

This seems to work but I have a couple of questions: 1. Are there any hidden gotchas with these method? I want to ensure I'm covering all cases where we can prevent a pull request being opened with a diff spanning the number of files > X. 2. Is it safe to call git fetch in a git hook? I need some way to ensure that the local reference origin/HEAD isn't stale otherwise the hook wouldn't fail but the pull request could still have an obscenely large diff if the local master is outdated.

Yes, the hidden gotcha here is that this service runs on developer machines, which means that the integrity of your CI system is based on developers' willingness and ability to install the pre-commit hook and not override it. As has been mentioned before here and elsewhere, it's impossible to rely on pre-commit hooks for policy enforcement, since developer machines are not trusted.

You'd be far better off putting this in your CI scripts and just fail early if the number of changes is large. Your CI system is the right place to make policy decisions, even if those policy decisions are to give up and not run the rest of the CI jobs. Alternately, if your Git server supports a pre-receive hook, you could do the work there.

In addition, pre-commit hooks like this make it difficult for advanced users to create a series of logical commits or even create fixup commits for squashing into an older commit. As one such user, I'd be very unhappy if I had to wait for a fetch every time I wanted to add some commits, and I expect your users will delete the hook or compulsively use --no-verify .

Having said that, it won't break anything to fetch in the pre-commit hook, although you will find that doing so will break users' use of git push --force-with-lease , along with potentially confusing editor integrations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM