# Sample Hooks

Place these as desired in `.git/hooks/` WITHOUT the suffix.

You will just need UV with pygittools in your virtual environment.

## post-receive.notify and post-commit.notify

Wake pygitweb's long-poll subscribers (`updates=true`) on every push (server-side) and
every local commit (client-side). They share two environment variables:

- `PYGITWEB_NOTIFY_URL` — the running server's notify endpoint (default
  `http://127.0.0.1:8000/_internal/notify`)
- `PYGITWEB_PROJECT` — project path as known to pygitweb (default: the bare repo's
  directory name with `.git` stripped, or for non-bare clones the working-tree directory
  name)

The pygitweb summary page can install both at once via the **Hooks** row (the `update`
bundle installs `post-commit.notify` and `post-receive.notify` together).

## pre-receive.protected-pattern

Reject pushes to protected refs when any newly introduced non-merge commit message does
not match a pattern. Merge commits are skipped by default; set `PYGITWEB_REJECT_MERGE_COMMITS=1`
to refuse merge commits and require squash or rebase instead.

Environment variables:

- `PYGITWEB_PROTECTED_REF_PATTERN` — refs to protect (default `^refs/heads/(main|master)$`)
- `PYGITWEB_COMMIT_MSG_PATTERN` — message regex (default `^(\S+): (.+)`)
- `PYGITWEB_REJECT_MERGE_COMMITS` — set to `1`/`true`/`yes` to reject merge commits

## pre-receive.branch-permissions

Enforce per-branch write permissions based on `auth.json` `oauth_permissions`. For each
updated branch ref (`refs/heads/*`), the hook:

- Builds a `project/branch` subject (e.g. `demo/main`, `demo/dev/alice.feature`).
- If any `pgw.write_branch.{scope}` keys match that subject, requires a matching grant.
- Otherwise, falls back to project write (`pgw.write.{project}`) for that project.

When no usable configuration or context is available, the hook is a no-op and allows
the push to proceed.

Environment variables:

- `PYGITWEB_PRINCIPAL` — principal identity string (email or username) to check grants for.
- `PYGITWEB_PROJECT` — project path as known to pygitweb (e.g. `demo`, `team/app`).
- `PYGITWEB_AUTH_CONFIG` — optional auth.json path (default: `~/.pygitweb/auth.json`).

## post-commit.push-remotes

After each local commit, force-with-lease push the current branch to every configured
remote when the branch name matches a pattern. Uses the git CLI (`git push
--force-with-lease`), so SSH remotes honor `~/.ssh/config` like a normal push. Push
failures are logged on stderr but do not affect the commit (post-commit hooks cannot undo
a commit).

Environment variables:

- `PYGITWEB_PUSH_BRANCH_PATTERN` — branch name regex (default `^wip/`)
- `GIT` — git executable (default: `git` on `PATH`)