Hooks in the Cloud
If you use GitHub, GitLab, or Bitbucket Cloud, you don't have filesystem access to the server's hooks/ directory. These platforms expose the same enforcement capabilities through GUI-configured policies that wrap the pre-receive mechanism internally.
GitHub:
- Branch Protection Rules / Rulesets: Require pull requests before merging, require status checks to pass, block force-pushes, require signed commits. These are configured under Settings > Branches.
- Pre-receive hooks are available only on GitHub Enterprise Server (self-hosted), where you upload scripts through the admin panel.
GitLab:
- Push Rules (Settings > Repository > Push Rules): Require commit messages to match a regex, reject unsigned commits, prevent pushing secrets, block files by name or size. Available on all tiers.
- Protected Branches: Restrict who can push or merge to specific branches.
Bitbucket:
- Branch Permissions: Restrict pushes, require pull requests, block force-pushes.
- Commit message enforcement is available via Marketplace plugins.
Under the hood, all of these platforms implement the same contract: before updating a ref, run a check. If the check fails, reject the push and return an error message to the client. The abstraction is different; the mechanism is identical to what you built in the lab.
The practical implication for platform engineers: when you join a team using hosted Git, your job is not to write Bash hooks — it's to configure these platform-level controls correctly, understand their limitations (e.g., GitHub's branch protection can be bypassed by repository admins), and layer additional controls (like CI status checks) on top of them.
Interviewers at companies using GitHub or GitLab will sometimes ask: "How do you enforce that all commits are linked to a ticket?" The answer should cover two layers: (1) a server-side control — GitLab Push Rules with a commit message regex, or a GitHub Enterprise pre-receive hook — that rejects non-compliant commits at push time; and (2) a CI check that validates the PR title or branch name against your issue tracker's API. Mentioning only one layer suggests you haven't thought about the failure modes of each approach.