Create a branch that is missing in the fork - #2
Merged
Conversation
Merged
'gh repo sync' updates a branch, it can't create one, so a branch listed in an '<organisation>.repos' file that the fork doesn't have yet can never be synchronized. Before synchronizing, the action now checks whether the fork has the branch, and creates it from the upstream repository's branch head when it doesn't. The upstream's commit is addressable through the fork, because GitHub keeps a fork and its upstream in one object network, so creating the branch is a single API call - no clone, fetch or push. This makes the '<upstream>' field functional: it names the repository the new branch's head is read from. A branch that exists in neither repository, a failed creation, and a missing branch while 'create-missing-branches' is disabled are counted errors. 'created' is a new output parameter. Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnpaXYDwfNwnJrQew78j3f
The branch head is read from '<upstream>', so a stale or copy-pasted upstream in a configuration file would create the branch from the wrong repository. Off by default; a repository enables it once its file was checked. While disabled, a missing branch stays a counted error naming the parameter. Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnpaXYDwfNwnJrQew78j3f
pytooling-claude
Bot
force-pushed
the
claude/create-missing-branches
branch
from
September 10, 2026 21:13
5fae190 to
b1aaa86
Compare
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New Features
A branch listed in an
<organisation>.reposfile that the fork doesn't have is created, from the upstreamrepository's branch head, and the next run synchronizes it like any other branch.
gh repo syncupdates a branch; it can't create one. So a branch added upstream after the fork was made — or everybranch but one, when the fork was made with Copy the default branch only — could never be synchronized: the entry
in the configuration file simply failed on every run, for ever.
create-missing-branchesenables it. It isfalseby default (second commit, on your call): the branch headis read from
<upstream>, so a stale or copy-pasted upstream would create the branch from the wrong repository, andeach repository should enable it once its configuration file has been checked. While disabled, a missing branch is a
counted error naming the parameter — which is already an improvement, because it says why the branch can't be
synchronized.
createdis a new output parameter and a new line in the summary.Changes
The mechanism is one API call, not fetch/push. You suggested fetch/pull/push; I checked whether the shorter path
works first, and it does — GitHub keeps a fork and its upstream in one object network, so the upstream's commit
is addressable through the fork and
POST /repos/<fork>/git/refsaccepts it directly.Verified read-only against real repositories before writing the code:
ghdl/ghdl'srustbranch isfa173d3bed630ee51f8c62426a12dd4748142a59,Paebbels/ghdlhas norustref (GET .../git/ref/heads/rust→404), and yet
GET /repos/Paebbels/ghdl/commits/fa173d3…returns that commit. The object is already there; only theref is missing.
That avoids cloning a repository per fork on the runner. A shallow fetch wouldn't help either — GitHub rejects a
push from a shallow clone ("shallow update not allowed"), so the fetch/push route would pull GHDL's full history
onto the runner to upload objects GitHub already has. If you'd rather have the git route regardless, it's a
self-contained replacement of one function.
<upstream>becomes functional. Until now it was reported; it is now the repository the new branch's head isread from.
This is why the parameter defaults to
false.PLC2/SynchronizeandVHDL/SynchronizenameOSVVM/osvvmas theupstream on every line of their
OSVVM.repos— 14 and 13 forks. GitHub resolves repository namescase-insensitively, so
OSVVM/osvvmis a real repository, and a missing branch in any of those 27 forks wouldotherwise be created from the wrong one. Enable the parameter per repository, after its file has been corrected.
The fork's branch is checked before synchronizing, one
gh apiread per branch, rather than after a failed sync.It costs ~50 reads per day for a namespace the size of
Paebbels, and in exchange the missing-branch case doesn'tdepend on parsing
gh's error text, and a doomedgh repo syncisn't run at all. Dry-run mode is unchanged andstill reads nothing.
Bug Fixes
path to a green run other than editing the configuration file or clicking through the GitHub UI.
Documentation
README.mdgains a Missing Branches section — whatgh repo synccan't do, what the action does instead, why<upstream>matters now, and the escape hatch. The parameter tables, the sample log and the summary block areupdated.
Unit Tests
check-outputsverifiescreatedtoo, and both verification jobs assert it.and a token. Four cases in the local harness cover it instead, against a stub
ghthat answersgit/ref/headswith 404 for a configured set of refs:
created=1, thePOSTcarriesref=refs/heads/devand the upstream SHA,and
gh repo syncis not called for it,POST,create-missing-branches: false→ counted error naming the parameter, and the upstream isn't evenread,
POSTthat fails → the message is quoted, annotated with%0Aescaping, and the fork appears inNot synchronized:.Related Issues and Pull-Requests
action.yml; whichever merges second rebases.🤖 Generated with Claude Code