Branch Protection & Pull Requests for Authors β
Why this page exists: In September 2026, SAP's Open Source Program Office (OSPO) applied an organization-wide branch-protection ruleset to every repository in the sap-tutorials GitHub organization. You can no longer push directly to the default branch (main or master). Every change β even a one-line typo fix β now goes through a pull request that must be reviewed and approved before it can be merged.
If you used to git push straight to main, this page is the new workflow you must follow. It explains the concepts (branches, forks, pull requests), the exact rules OSPO enforces, and gives you step-by-step instructions for both the web UI and the command line.
IMPORTANT
This changes how you get content in, not what you write or what happens after merge. Once your PR is merged, the publish pipeline behaves exactly as before β see writing-tutorials.md Β§7 "What happens after merge".
1. The rules, in one table β
These are the actual rules enforced by the OSPO ruleset "Protect default branch (org-wide)", applied to the default branch of every repo in sap-tutorials. Verified live via the GitHub API on 2026-09-23.
| Rule | What it means for you |
|---|---|
| No direct pushes | You cannot git push to main/master. The push is rejected. All changes arrive via pull request. |
| Pull request required | Every change to the default branch must go through a PR. |
| β₯ 1 approving review | A PR needs at least one approval from someone other than the author before it can merge. |
| Stale reviews dismissed on push | If you push new commits after getting an approval, that approval is cleared and you must be re-approved. |
| Extra approval for unattributed changes | If a commit's author can't be matched to a GitHub identity (e.g. a bad user.email), the PR needs an additional approval. Set your git identity correctly to avoid this β see Β§7. |
| No force-pushes | git push --force to the default branch is blocked (non_fast_forward). |
| No branch deletion | The default branch cannot be deleted. |
| No bypass | There is no bypass list. Repo admins and org owners follow the same rules β nobody can push directly. |
What is NOT required (so you don't over-think it): code-owner review is not mandated, last-push approval is not required, and review-thread resolution is not enforced by the rule. All three merge methods (merge, squash, rebase) are allowed.
NOTE
The rule targets ~DEFAULT_BRANCH, so it protects whatever the repo's default branch is named. Most tutorial repos use main; a few older ones (e.g. Tutorials) still use master. The protection applies either way. This guide writes main β substitute master where your repo uses it. Check with git remote show origin | grep "HEAD branch".
2. Concepts you need (branch, fork, pull request) β
If these terms are already second nature, skip to Β§4.
2.1 Branch β
A branch is a parallel line of work inside a repository. The default branch (main) is the "official" version that the tutorial platform publishes from. When you create a branch, you get an isolated copy of the files where you can commit freely without touching main.
main: AβββBβββC β protected, publishes to developers.sap.com
\
your-branch: DβββE β your work-in-progress, safe to pushYou do your editing on your branch, then propose merging it back into main via a pull request.
2.2 Fork β
A fork is your personal copy of the entire repository under your own GitHub account (your-username/abap-core-development). It's a separate repo that remembers where it came from ("upstream"). You push branches to your fork, then open a PR from your fork into the upstream sap-tutorials repo.
Do you need a fork? It depends on your access:
| Your situation | Use | Why |
|---|---|---|
You have write (push) access to the sap-tutorials repo | Branch directly in the repo (Β§4) | Simpler β no fork to keep in sync. You still cannot push to main, only to your own branch. |
| You are an external contributor with no write access | Fork (Β§5) | You can't create branches in a repo you can't push to. Fork, branch in your fork, PR upstream. |
| Not sure | Try Β§4; if git push to a new branch is rejected with a permissions error, use Β§5 | β |
Both paths end at the same place: a pull request into the protected main.
2.3 Pull request (PR) β
A pull request is a proposal: "please merge the commits on my branch into your main." It's where review happens β a reviewer reads the diff, comments, and clicks Approve. Once the PR has the required approval and passes any checks, it can be merged, which is the only way changes now reach main.
3. The new workflow at a glance β
OLD (no longer possible) NEW (required)
ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββ
edit on main 1. branch off main (or fork, then branch)
git commit 2. edit + commit on the branch
git push origin main β REJECTED 3. push the branch (to repo or your fork)
4. open a pull request β main
5. get β₯ 1 approval
6. merge the PR β this reaches main
7. pipeline publishes (unchanged)4. Step by step β you HAVE write access (branch in the repo) β
Use this if you can push to the sap-tutorials repo (most SAP-internal authors and repo group owners).
4.1 Command line β
# 1. Clone (once) and move into the repo
git clone https://github.com/sap-tutorials/abap-core-development.git
cd abap-core-development
# 2. Make sure you start from the latest main
git checkout main
git pull origin main
# 3. Create a branch β name it after your change
git checkout -b fix/typo-in-abap-cloud-ui
# 4. Edit your .md files / add images, then stage and commit
git add tutorials/abap-cloud-ui-from-interface.md
git commit -m "Fix broken image path in abap-cloud-ui-from-interface"
# 5. Push YOUR BRANCH (never main)
git push -u origin fix/typo-in-abap-cloud-ui
# 6. Open the PR (gh CLI). --base main --head is your branch (implied by -u above)
gh pr create --base main \
--title "Fix broken image path in abap-cloud-ui-from-interface" \
--body "Corrects a relative image path that 404'd on the published page."gh pr create prints the PR URL. Share it, or wait for a reviewer to pick it up.
4.2 Web UI (no local git) β
You can do the whole thing in the browser β good for quick text edits:
- Browse to the file on
github.com/sap-tutorials/<repo>. - Click the pencil (Edit) icon.
- Make your edit.
- Click Commit changesβ¦. GitHub will not let you commit to
main; it offers "Create a new branch for this commit and start a pull request." Leave that selected, name the branch, and click Propose changes. - On the next screen, click Create pull request.
That's the same result as the CLI path β a branch plus a PR into main.
5. Step by step β you do NOT have write access (fork + PR) β
Use this if you're an external contributor or git push to a new branch fails with a 403/permission error.
# 1. Fork via the CLI (or click "Fork" on the repo page in the browser)
gh repo fork sap-tutorials/abap-core-development --clone
cd abap-core-development
# gh sets up two remotes for you:
# origin β your fork (you can push here)
# upstream β sap-tutorials/... (you open PRs against this; read-only to you)
# 2. Start from an up-to-date main
git checkout main
git pull upstream main
# 3. Branch, edit, commit
git checkout -b add/new-hana-tutorial
git add tutorials/my-new-tutorial.md tutorials/my-new-tutorial/
git commit -m "Add tutorial: my-new-tutorial"
# 4. Push the branch to YOUR FORK (origin)
git push -u origin add/new-hana-tutorial
# 5. Open the PR from your fork into upstream main
gh pr create --repo sap-tutorials/abap-core-development \
--base main --head <your-github-username>:add/new-hana-tutorial \
--title "Add tutorial: my-new-tutorial" \
--body "New beginner tutorial for SAP HANA Cloud."Keeping your fork current (do this before starting new work, so you branch from fresh code):
git checkout main
git pull upstream main # pull the org's latest
git push origin main # update your fork's main to match6. Getting your PR approved and merged β
- Request a review. In the PR page, under Reviewers, request your repo group owner, or ask in the platform team channel. A reviewer must click Approve β your own review does not count toward the required approval.
- Address feedback. If the reviewer requests changes, commit them on the same branch and push again. The PR updates automatically.
- β οΈ Pushing after an approval clears that approval (the "dismiss stale reviews" rule). You'll need the reviewer to approve again. Batch your fixes to minimize round-trips.
- Merge. Once you have β₯ 1 approval (and any checks are green), click Merge pull request (or
gh pr merge --squash). Squash keeps the history tidy; any of the three methods is allowed. - Delete the branch. GitHub offers a Delete branch button after merge β safe to click; it only removes your feature branch, never
main. - Publish is automatic. Merging to
mainfires the repo-dispatch pipeline. Your tutorial is live in a minute or two β see writing-tutorials.md Β§7.
7. Avoiding the "unattributed changes" extra-approval trap β
The ruleset requires an extra approval when a commit's author can't be attributed to a GitHub account. This almost always means your local git identity doesn't match your GitHub email. Fix it once:
git config --global user.name "Your Name"
git config --global user.email "your-github-email@example.com" # must match a verified GitHub emailUse the email listed under GitHub β Settings β Emails (or your @users.noreply.github.com address). If a PR already shows "unverified"/unattributed commits, re-committing with the correct identity and re-pushing clears it; otherwise you'll simply need a second approver.
8. Troubleshooting β
| Symptom | Cause | Fix |
|---|---|---|
! [remote rejected] main -> main (protected branch hook declined) | You tried to push directly to main. | Push a branch instead (Β§4/Β§5) and open a PR. |
remote: Permission to sap-tutorials/<repo>.git denied on git push | No write access to the repo. | Use the fork workflow (Β§5). |
| PR says "Merging is blocked β review required" | No approving review yet. | Request a reviewer (Β§6.1); your own approval doesn't count. |
| Your approval vanished after you pushed a fix | "Dismiss stale reviews on push" is on. | Re-request approval; batch changes next time. |
| PR wants a second approval unexpectedly | Commit is unattributed. | Fix git identity (Β§7); re-approval or a second approver clears it. |
git push --force rejected | Force-push to a protected branch is blocked. | Don't force-push shared branches; if you must rewrite, do it on your feature branch before others pull it. |
| I'm a repo admin β can't I just bypass? | The ruleset has no bypass list. | No. Everyone uses PRs, including admins. |
9. FAQ β
Do I need this for the -Contribution (QA) repos too? The ruleset targets every repo's default branch in the org, so treat *-Contribution repos the same way β branch/fork and PR. QA preview then works as described in writing-tutorials.md Β§5.1.
Can I still make quick typo fixes? Yes β the fastest path is the web-UI edit (Β§4.2). GitHub auto-creates the branch and PR for you; you still need one approval.
Who approves my PR? Your repo group owner is the default reviewer. For cross-cutting or platform changes, ask in the platform team channel.
Does the merge method matter? Not for the rules β merge, squash, and rebase are all allowed. Squash is recommended to keep one clean commit per change.
Where do I see the rule itself?github.com/sap-tutorials/<repo>/rules β the repo's Settings β Rules (read-only for non-admins), or the branch-protection banner shown on a blocked push.
Reference: related docs β
- writing-tutorials.md β authoring workflow, local preview, what happens after merge (Β§4 there now points here)
- repo-group-owners.md β for the people who review and approve your PRs
- tutorial-repo-dispatch.yml β the Action that triggers a rebuild once your PR is merged
- GitHub Docs: About pull requests
- GitHub Docs: About rulesets