Let me start by reading the knowledge graph and the pages manifest, then explore the relevant source files.
Now let me look at the config schema for branch protection, cherry-pick, and OWNERS-related settings:
Now let me look at the issue_comment handler for cherry-pick commands and the PR handler's cherry-pick sections:
Now let me look at the cherry_pick method and the auto-verify cherry-pick logic:
Now let me look at the cherry-pick retry command and the welcome message cherry-pick section:
Now let me look at the protected-branches configuration and how it connects to status checks:
Let me also check the _prepare_merge_requirements for OWNERS file info:
Now let me look at the ROOT_APPROVERS_KEY constant and the merge requirements with OWNERS file checking:
Let me check the approve flow to understand how OWNERS file approvers control merge:
Now I have all the information I need. Let me write the documentation page.
Cherry-Picking and Branch Protection
Automate the process of backporting merged PRs to release branches and enforce consistent branch protection rules across your repositories, using OWNERS files to control who can approve changes.
Prerequisites
- A running webhook server instance (see Getting Started)
- At least one repository configured in
config.yaml(see Configuring Repositories) - A GitHub App installed on your repositories with branch protection permissions
Quick Example
Add cherry-pick targets and branch protection to your repository configuration:
# config.yaml
cherry-pick-assign-to-pr-author: true
auto-verify-cherry-picked-prs: true
branch-protection:
strict: true
required_approving_review_count: 1
required_conversation_resolution: true
repositories:
my-repo:
name: my-org/my-repo
protected-branches:
main: []
release-1.0: []
Then create an OWNERS file in your repository root:
approvers:
- alice
- bob
reviewers:
- charlie
- dana
When a PR is merged, comment /cherry-pick release-1.0 to backport it — or add the label before merging so it happens automatically.
Cherry-Picking PRs to Target Branches
Scheduling a Cherry-Pick Before Merge
Comment on an open PR to queue cherry-picks for when it merges:
/cherry-pick release-1.0
This adds a cherry-pick-release-1.0 label to the PR. When the PR merges, the server automatically cherry-picks the merge commit to the release-1.0 branch and opens a new PR.
You can specify multiple branches at once:
/cherry-pick release-1.0 release-2.0 hotfix
Each branch gets its own cherry-pick-<branch> label, and each is processed independently on merge.
Cherry-Picking an Already-Merged PR
Comment on a merged PR to cherry-pick immediately:
/cherry-pick release-1.0
For merged PRs, the cherry-pick executes right away instead of waiting. A cherry-pick-release-1.0 label is added to track that the operation was performed.
What Happens During a Cherry-Pick
When a cherry-pick is triggered, the server:
- Validates the target branch exists
- Creates a worktree and checks out the target branch
- Runs
git cherry-pick <merge-commit-sha>(automatically retries with-m 1for merge commits) - Restores the original PR author on the cherry-pick commit (for DCO/sign-off compliance)
- Runs pre-commit hooks if enabled for the repository
- Pushes the new branch and opens a PR against the target branch
- Labels the new PR with
CherryPicked-from-<source-branch> - Assigns the original PR author and requests their review
If the cherry-pick fails due to conflicts and AI conflict resolution is not enabled (or fails), the server posts a comment with manual cherry-pick instructions:
**Manual cherry-pick is needed**
Cherry pick failed for abc1234 to release-1.0:
To cherry-pick run:
git remote update
git checkout release-1.0
git pull origin release-1.0
git checkout -b my-feature-release-1.0
git cherry-pick abc1234
# If the above fails with 'is a merge but no -m option', run:
# git cherry-pick -m 1 abc1234
git push origin my-feature-release-1.0
Retrying a Failed Cherry-Pick
If a cherry-pick fails or the resulting PR has issues, use the retry command on the original merged PR:
/cherry-pick-retry release-1.0
This command:
- Validates the PR is merged and has the
cherry-pick-release-1.0label - Closes any existing failed cherry-pick PR created by the bot for that branch
- Re-runs the cherry-pick operation
Note:
/cherry-pick-retryaccepts exactly one branch name. If the cherry-pick label doesn't exist on the PR, use/cherry-pick <branch>instead.
Duplicate Prevention
If a cherry-pick-<branch> label already exists on the PR, that branch is skipped. To re-trigger a cherry-pick for a branch that was already processed, remove the label and run the command again.
Auto-Verification of Cherry-Picked PRs
By default, cherry-picked PRs from auto-verified users are automatically marked as verified. Control this behavior globally or per-repository:
# Global setting (default: true)
auto-verify-cherry-picked-prs: true
repositories:
my-repo:
name: my-org/my-repo
# Override per repository
auto-verify-cherry-picked-prs: false
When set to false, cherry-picked PRs require manual verification even if the original author is in the auto-verified-and-merged-users list.
Warning: Cherry-picked PRs with AI-resolved conflicts are never auto-verified, regardless of this setting. The
ai-resolved-conflictslabel forces manual review.
Cherry-Pick PR Assignment
By default, cherry-pick PRs are assigned to the original PR author. Disable this globally or per-repository:
# Global setting (default: true)
cherry-pick-assign-to-pr-author: true
repositories:
my-repo:
name: my-org/my-repo
cherry-pick-assign-to-pr-author: false
When the original author cannot be assigned (e.g., they don't have repository access), the server falls back to assigning the first root approver from the OWNERS file.
Configuring Branch Protection
Branch protection rules are applied to every branch listed under protected-branches for a repository. Configure the rules at the global level, the repository level, or both (repository overrides global).
Branch Protection Settings
branch-protection:
strict: true
require_code_owner_reviews: false
dismiss_stale_reviews: true
required_approving_review_count: 0
required_linear_history: true
required_conversation_resolution: true
| Setting | Default | Description |
|---|---|---|
strict |
true |
Require branches to be up-to-date before merging |
require_code_owner_reviews |
false |
Require review from code owners |
dismiss_stale_reviews |
true |
Dismiss approvals when new commits are pushed |
required_approving_review_count |
0 |
Minimum number of GitHub review approvals |
required_linear_history |
true |
Require linear commit history (no merge commits) |
required_conversation_resolution |
true |
Require all review conversations to be resolved |
Tip: The
required_conversation_resolutionsetting also controls whether the server checks for unresolved review threads when evaluating thecan-be-mergedcheck run.
Defining Protected Branches
List the branches to protect under protected-branches in your repository config. Each branch can specify which status checks are required:
repositories:
my-repo:
name: my-org/my-repo
protected-branches:
main:
include-runs:
- "pre-commit.ci - pr"
- "WIP"
exclude-runs:
- "SonarCloud Code Analysis"
dev: []
release-1.0: []
Three formats are supported:
| Format | Example | Behavior |
|---|---|---|
| Empty list | dev: [] |
Auto-detects status checks from repo config (tox, pre-commit, container builds, etc.) |
| Include/exclude object | main: { include-runs: [...], exclude-runs: [...] } |
Explicitly controls which checks are required |
| Simple array | feature: ["check1", "check2"] |
Uses only the listed checks |
When you use the empty list [], the server automatically builds the required status checks from your repository configuration — if tox is enabled it adds tox, if container is configured it adds build-container, and so on. The can-be-merged and verified checks are always included by default.
Per-Repository Branch Protection Overrides
Override global branch protection at the repository level:
branch-protection:
strict: true
required_approving_review_count: 0
repositories:
strict-repo:
name: my-org/strict-repo
branch-protection:
required_approving_review_count: 2
dismiss_stale_reviews: true
protected-branches:
main: []
Repository-level settings override global settings for the same key. Any keys not specified at the repository level fall back to the global value, then to the built-in defaults.
Using OWNERS Files for Approval Workflows
OWNERS files define who can approve and review PRs for specific parts of your codebase. The server reads these files from the repository's base branch and uses them to enforce approval requirements.
OWNERS File Format
Create an OWNERS file (YAML format) in any directory:
approvers:
- alice
- bob
reviewers:
- charlie
- dana
- Approvers can use the
/approvecommand to approve PRs touching files in that directory - Reviewers are automatically assigned to PRs and can use
/lgtm
Directory-Scoped Ownership
Place OWNERS files in subdirectories to define granular ownership:
repo-root/
├── OWNERS # Root approvers/reviewers (apply to all PRs)
├── api/
│ └── OWNERS # Approvers for API changes
├── frontend/
│ └── OWNERS # Approvers for frontend changes
└── docs/
└── OWNERS # Approvers for documentation
When a PR changes files in api/, the server requires approval from an approver listed in api/OWNERS. Root approvers (from the repository root OWNERS) can always approve any PR.
Controlling Root Approver Requirements
By default, root approvers are always required in addition to directory-specific approvers. Override this by adding root-approvers: false to a subdirectory's OWNERS file:
# api/OWNERS
approvers:
- api-lead
reviewers:
- api-dev
root-approvers: false
With root-approvers: false, only the approvers listed in api/OWNERS need to approve changes under api/ — root approvers are not required for those files.
Note: If a PR changes files in both
api/(withroot-approvers: false) and an unmatched directory, root approvers are still required for the unmatched files.
How Approval Checking Works
The server evaluates approvals when determining if a PR can be merged:
- For each changed file, the server finds the most specific
OWNERSfile - At least one approver from each relevant
OWNERSfile must use/approve - A root approver's
/approvesatisfies all directory requirements - If a reviewer uses
/lgtm, it counts toward theminimum-lgtmthreshold but does not count as an approval - Change requests from approvers block the
can-be-mergedcheck
Automatic Reviewer Assignment
When a PR is opened, reviewers from all relevant OWNERS files are automatically assigned. You can also trigger this manually:
/assign-reviewers
Or assign a specific reviewer:
/assign-reviewer @username
Allowed Users
The OWNERS file in the repository root can include an allowed-users list to grant command execution permissions:
# Root OWNERS file
approvers:
- alice
reviewers:
- bob
allowed-users:
- external-contributor
Users not in the approvers, reviewers, collaborators, or contributors lists need explicit permission via allowed-users or a maintainer commenting /add-allowed-user @username on the PR.
Advanced Usage
AI-Powered Cherry-Pick Conflict Resolution
When a cherry-pick encounters merge conflicts, the server can use AI to attempt automatic resolution. See Enabling AI Features for setup details.
ai-features:
ai-provider: claude
ai-model: sonnet
resolve-cherry-pick-conflicts-with-ai:
enabled: true
timeout-minutes: 10
When AI resolves conflicts:
- The cherry-pick PR is labeled with
ai-resolved-conflicts - The PR is never auto-verified — manual review is always required
- The server logs a scope verification comparing original vs. cherry-picked file counts
- If AI resolution fails, the server falls back to posting manual cherry-pick instructions
Combining Cherry-Pick Labels with Enabled Labels
Cherry-pick labels (cherry-pick-<branch> and CherryPicked) belong to the cherry-pick label category. If you use enabled-labels to restrict which labels are active, include cherry-pick to keep cherry-pick functionality working:
labels:
enabled-labels:
- verified
- cherry-pick
- can-be-merged
See Configuring Labels and PR Size Thresholds for full label configuration options.
Default Status Checks
Override which status checks are added by default to all protected branches:
# Global defaults
default-status-checks:
- "WIP"
- "dpulls"
- "can-be-merged"
repositories:
my-repo:
name: my-org/my-repo
# Override for this repo only
default-status-checks:
- "WIP"
- "can-be-merged"
- "ci/my-external-check"
These checks are combined with auto-detected checks (tox, pre-commit, etc.) when a protected branch uses the empty list [] format.
Troubleshooting
Cherry-pick label exists but cherry-pick didn't run
Cherry-picks only execute when a PR is merged (for pre-merge labels) or immediately (for post-merge /cherry-pick commands). If the PR was closed without merging, cherry-pick labels are ignored. Re-open and merge the PR, or use /cherry-pick <branch> on the merged PR.
"Target branch does not exist" error The server validates that each target branch exists before adding cherry-pick labels. Check that the branch name matches exactly (branch names are case-sensitive).
Cherry-pick PR is not auto-verified
Check whether auto-verify-cherry-picked-prs is set to false for the repository. Also check if the cherry-pick had AI-resolved conflicts — PRs with the ai-resolved-conflicts label are never auto-verified.
Branch protection not applied to a branch
Only branches listed under protected-branches in the repository config receive protection rules. The repository must also be public — private repositories skip branch protection settings.
"/approve not accepted" from a user
The user must be listed as an approver in a relevant OWNERS file. Reviewers can use /lgtm but cannot /approve. Check which OWNERS file covers the changed files and verify the username spelling.