Configure GitHub Repository Protection
How to apply a set of repository settings that keep the codebase clean and protect the default branch on GitHub.
You must have Admin or Owner permissions on the repository to access and change any of the settings below. All settings are found under Settings → General → Pull Requests unless stated otherwise.
For the reasoning behind these settings, see GitHub Branch Protection Rationale. For the CI path-filtering pattern these rules depend on, see GitHub CI Path Filtering.
Table of Contents
- Automatically delete head branches
- Always suggest updating pull request branches
- Protect the default branch against force pushes and deletion
- Require status checks before merging
- Require a pull request before merging
Automatically delete head branches
When a feature branch is merged into main, it has served its purpose. Enable GitHub’s built-in setting to delete the head branch of a pull request as soon as it is merged. The setting applies to all future merges — no action is required per pull request.
Steps
- Navigate to the main page of the repository on GitHub and click the Settings tab.
- Scroll down the General settings page to the Pull Requests section.
- Check the box labelled Automatically delete head branches.
The change is saved instantly — there is no separate Save button for this option.
What happens next
- After each pull request is merged, GitHub deletes the head branch automatically.
- The merged pull request page will show a Restore branch button, allowing any collaborator to recreate the branch if further work is needed (for example, to add a hotfix on top of the same base).
- Branches that are not yet merged are never deleted by this setting; only branches whose pull request has been fully merged are affected.
Restoring a deleted branch
If a branch was deleted by mistake, it can be restored from the closed pull request:
- Navigate to Pull requests → Closed.
- Open the relevant pull request.
- Click Restore branch at the bottom of the conversation timeline.
The branch is recreated at the exact commit SHA it pointed to before deletion.
Reference: Managing the automatic deletion of branches
Always suggest updating pull request branches
When a pull request’s base branch receives new commits after the pull request was opened, the head branch may fall behind. GitHub can display a prominent Update branch button on every open pull request to remind contributors to rebase or merge the latest changes before their PR is reviewed or merged.
Steps
- Navigate to the main page of the repository on GitHub and click the Settings tab.
- Scroll down the General settings page to the Pull Requests section.
- Check the box labelled Always suggest updating pull request branches.
The change is saved instantly.
What happens next
- GitHub displays an Update branch button on every open pull request whose head branch is behind the base branch.
- Contributors can click Update branch to merge the base branch into their head branch directly from the pull request page — no local rebase is required.
- The suggestion is informational; contributors are not forced to update before merging.
Reference: Keeping your pull request in sync with the base branch
Protect the default branch against force pushes and deletion
Protect the default branch (main) from history rewrites and accidental deletion. For why these two protections matter, see GitHub Branch Protection Rationale.
Steps
All settings are found under Settings → Branches → Branch protection rules. Edit (or create) the rule that applies to main (or your default branch pattern).
- Navigate to the main page of the repository on GitHub and click the Settings tab.
- In the left sidebar click Branches, then click Edit next to the rule for
main(or Add branch protection rule if none exists yet, enteringmainas the branch name pattern). - Scroll to the Push restrictions section and check Do not allow bypassing the above settings if you want the protection to apply even to administrators.
- Check Restrict force pushes — this blocks all
git push --forceandgit push --force-with-leasecommands targeting the protected branch. - Check Do not allow deletions — this prevents the branch from being deleted via the GitHub UI, the API, or the command line.
- Click Save changes.
What happens next
- Any attempt to force-push to
mainis rejected by GitHub with the error:remote: error: GH006: Protected branch update failed, force push prohibited. - Any attempt to delete
mainviagit push origin --delete mainor the GitHub UI is blocked. - Normal pushes and pull request merges are not affected — only destructive rewrites and deletions are prevented.
- Repository admins can still perform force pushes or deletions if the Allow force pushes option is granted to admins, but checking Do not allow bypassing the above settings disables even that escape hatch.
Reference: About protected branches
Require status checks before merging
Configure GitHub to block merges until specific CI status checks have passed, turning the CI pipeline into an enforced quality gate. This rule depends on the in-workflow path-filtering pattern described in GitHub CI Path Filtering; for why trigger-level paths filters break required checks in a monorepo, see GitHub Branch Protection Rationale.
Steps
This repository enforces required checks through a repository Ruleset, not a classic branch protection rule. All settings are found under Settings → Rules → Rulesets. Edit (or create) the ruleset that targets main.
- Navigate to the repository Settings tab.
- In the left sidebar click Rules → Rulesets, then click New ruleset → New branch ruleset (or Edit the existing ruleset that targets
main). - Give the ruleset a name (for example,
main) and set Enforcement status to Active. - Under Target branches, click Add target → Include default branch (or Add by pattern and enter
main). - In the Rules list, check Require status checks to pass.
- Click Add checks and, in the search box that appears, type the name of each job you want to require and select it:
java-build-and-testreact-build-and-test
Do not add
skip-check. When a required job is skipped (because no relevant files changed), GitHub automatically counts it as passing. Addingskip-checkas a required check is not needed and would cause PRs to be blocked whenever only one stack’s files are changed (sinceskip-checkfor the other stack would be skipped but not passing from GitHub’s perspective). - Optionally check Require branches to be up to date before merging to ensure CI always runs against the latest base branch.
- Click Create (or Save changes when editing an existing ruleset).
Tip: the job name added to the ruleset must match the job
idin the workflow YAML exactly (case-sensitive). GitHub will not offer auto-complete for jobs that have never run, so trigger the workflow at least once — by opening a draft pull request — before configuring the ruleset.
What happens next
- GitHub blocks the merge button until all required checks report green.
- A PR that breaks the backend build will show a red
java-build-and-testcheck and cannot be merged. - A documentation-only PR will see
skip-checkpass for both workflows and can be merged immediately.
See the status-reporting matrix for the exact outcome of each change scenario.
Reference: About required status checks
Require a pull request before merging
Require a pull request before merging so that direct pushes to main are rejected and every change must pass the required status checks. For the gap this closes, see GitHub Branch Protection Rationale.
Steps
All settings are found under Settings → Branches → Branch protection rules. Edit (or create) the rule for main.
- Navigate to the repository Settings tab.
- In the left sidebar click Branches, then click Edit next to the
mainrule. - Check Require a pull request before merging.
- Optionally increase Required number of approvals if your team practices peer review.
- Click Save changes.
Combine this rule with the Require status checks to pass ruleset setting (see the section above) to ensure every commit on
mainhas been built and tested before it arrives.
What happens next
- Any attempt to push directly to
mainis rejected by GitHub with the error:remote: error: GH006: Protected branch update failed, direct push to protected branch not allowed. - All changes must be submitted as pull requests. The PR is only mergeable once all required status checks report green.
- Repository admins retain the ability to bypass the rule unless Do not allow bypassing the above settings is also checked.
- The
pushtrigger in the CI workflows continues to function: when a PR is merged, GitHub creates a merge commit onmain, which fires thepushevent. The workflows use this for any post-merge steps (for example, tagging a release or deploying to an environment).
Reference: About protected branches