In general, you cannot reliably prevent someone from making changes to their local repositories. If you do not trust your developers to never make mistakes (in which case you will not need it), you should run your checks on hooks on your server.
This means that you cannot count on preventing the fork of people, and I'm not sure why you really wanted to. What you can do is get people to push away work that has not been "approved" in the server deployment branch (which I will call deploy ).
Now the first question is how to express this statement.
If you need a workflow where an authorized person needs to check the work before deploying it, I would ask the reviewer to follow these steps if the work currently lives in branches called review :
- Make sure
deploy fully integrated with review , so deploy can be quickly redirected to review later. - Do any appropriate
review . - Create and click the signed tag (
git tag -s ) using an authorized key for the review content. - Fast forward
deploy to review ( git checkout deploy , git merge --ff-only review ) and click.
If instead you want someone to be able to deploy, but you want them to think about it first, you could do the same thing except debug the signature requirements. Or you can bless a particular branch ( tested , say) and require that all work be merged and clicked on tested before it is moved to deploy .
How can the server verify that this permission has been granted for the deploy branch? The basic plan is to use the update hook to accept or reject ref-updates for refs/heads/deploy in accordance with the acceptance criteria that you decided on.
If you need a tag that meets certain criteria, for example, is signed with an approved key, you can find all the tags that point to the new object offered for deployment using git for-each-ref refs/tags . Remember to accept the update if any tag meets the criteria, or sooner or later someone is going to click on a bad tag that blocks deployment. Checking that the right key has been used remains as an exercise for the reader, but gpg --no-default-keyring --keyring=approved.gpg can help.
If you make a commit while someone is tagging it, you can use git describe --exact-match <object> . If you want to restrict to tags with a specific name pattern, add --match <pattern> . If you accept unannotated tags, add --tags .
If you want the work to be merged with a blissful branch before merging with the deployment, you can verify that the output of git rev-parse tested is equal to the proposed new object.
In all cases, you probably want to double-check that clicking is a quick redirect. You can verify that git merge-base <old> <new> is equal to <old> .