pre-receive git hook to reject force but allow force-with-lease push

Viewed 79

Is it possible to create a server-side pre-receive git hook to reject push with --force but not reject push with --force-with-lease?

1 Answers

There is no way to do that because they look identical to the server.

The way a Git ref update works is that the client asks the server to update a given ref from an old value to a new value. On the server side, Git can tell if the old value is an ancestor of the new value (a regular push) or not (a force push), and act accordingly. However, in either case, the old value must match the current value on the server; if it does not, the ref update will fail, because that means that you've raced with someone else that's pushing.

In most cases, when you do a ref update with --force, the old value is whatever the server advertised in its ref advertisement. What --force-with-lease does is it asks Git to specify the old value not from what the server has advertised, but from the remote tracking branch or the value specified by the user. However, the server doesn't know that the user has specified this option. All it knows is whether the old value matches (which is always required) and whether it's a parent of the new value (in which case it's a force push).

Related