Skip to content

chore(#803): persistent fork checkout replaces the clone-per-task pattern - #927

Merged
gsdali merged 1 commit into
mainfrom
chore/803-upstream-fork-checkout
Aug 17, 2026
Merged

chore(#803): persistent fork checkout replaces the clone-per-task pattern#927
gsdali merged 1 commit into
mainfrom
chore/803-upstream-fork-checkout

Conversation

@gsdali

@gsdali gsdali commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator

What & why

#803 asked for two things: post two staged upstream replies, then move upstream work off disposable
shallow clones onto a branch checkout of our own fork. Part 1 had largely overtaken itself between
the issue being filed and this branch, so it is closed out on evidence rather than acted on. Part 2
is the real change.

Closes #803

Nothing is owed upstream, and nothing was posted from this branch. Verified directly rather than
inherited:

PR State What happened to its staged reply
OCCT#1418 (#522) merged 2026-08-10, dpasukhi, "Thank you for the patch!" never posted, and now moot
OCCT#1417 (#555) closed 2026-08-10, state_reason: null, no closing comment superseded
OCCT#1457 (#555) open, same head branch fix/555-gcpnts-point-count posted 2026-08-10 as issuecomment-5246831466

A sweep of all fifteen currently open gsdali-authored upstream PRs finds no maintainer comment or
review left unanswered. The only one where a maintainer has the last word is
OCCT#1388, and it is gkv311 acknowledging our
own answer ("indeed, thanks for pointing out"), not a question.

One correction to the issue's premise

#803 says Libraries/occt-src "is already a full clone of upstream". It is not:
Scripts/build-occt.sh:97 creates it with git clone --depth 1, and
Libraries/occt-src/.git/shallow is present. That matters, because the shallow boundary is the exact
thing that closed OCCT#1417.

What each staged file got, and why

The repro directories are kept, per #803. The four staged files each get a status header instead,
because the trap #803 was filed about is a file that reads as an unsent draft when it was sent, or as
sendable when it is moot. Deleting them would have removed the record of both.

  • 555-gcpnts-count-contract/upstream/reply-to-gkv311.md: posted. The two-line drafting note
    ("not yet posted", naming #1417) is replaced by a header recording that it went to #1457, why the
    PR number moved, and that its "Pushed an update addressing all three points" opening is accurate.
    Re-verified after editing: everything below the rule is still byte-identical to the live comment.
    The staged 0001-gcpnts-review-fixes.patch is on the branch as 8adab6565, hunks identical bar
    one blank line.
  • 522-approx-c0-collapse/upstream/reply-to-gkv311.md: never posted. Header records that, and
    names the two things its body describes as done that were never done (the description rewrite, the
    Draw test). Without that, the body still misleads.
  • 522-approx-c0-collapse/upstream/pr-1418-description.md: never applied. #1418 merged with its
    original description.
  • 522-approx-c0-collapse/upstream/tests/bugs/moddata_3/bug1418: never contributed. Its own
    "rename this at merge time" note was stale the moment #1418 merged without it.

#803's three drafting corrections (the internal scaffolding in #1417's first three lines, the "did
not have the OCCT tree checked out" sentence, the bug23942 idiom claim) are recorded as never
applied. The first turned out to be moot already: the scaffolding was stripped at post time, as
§7 requires. The other two only mattered if the 522 reply were still going to be sent, and it is not.

The fork checkout

~/Projects/occt-upstream, outside every OCCTSwift checkout, shared by every worktree. Blobless
clone of gsdali/OCCT with Open-Cascade-SAS/OCCT wired as upstream, also blobless. Set up and
verified, nothing pushed:

  • git rev-parse --is-shallow-repository answers false, 7136 commits reachable on upstream/master
  • 367 MB total, 80 MB of it .git
  • all 15 open PR branches present; fix/555-gcpnts-point-count checked out
  • HEAD is 06d807ff1, git merge-base HEAD upstream/master is 7d2efad9c, and those match
    #1457's live head.sha and base.sha exactly
  • git cat-file -p HEAD shows two real parents, which is the footgun-A check passing

Why there, and what was rejected

Libraries/occt-src with the fork added as a remote is #803's own floated option. Rejected on four
counts, each checked:

  1. It is itself a --depth 1 clone, so branching there inherits the boundary that closed #1417.
  2. Libraries/ is gitignored in full and is per-worktree. This worktree has no Libraries/ at all,
    so the checkout would be re-cloned per worktree, which is the thing Post-release: post the two staged upstream replies, and move to branch checkouts of our own fork #803 asked to avoid.
  3. Its working tree is permanently dirty by design: build-occt.sh applies every carried patch to
    the working tree, not to HEAD, and relies on git apply --reverse --check to stay idempotent.
  4. build-occt.sh:110-123 reuses the tree only when git describe --tags --exact-match HEAD equals
    the tag it builds. A branch checkout fails that test, and the error it prints tells you to
    rm -rf occt-src, which would take unpushed branch work with it.

Gitignoring a checkout inside the repo was rejected for reason 2 alone: anything under the repo path
is per-worktree.

Where it is documented

okf/policies/upstream-occt-patch-process.md, as a new §0, plus a rewritten §6. Not a new file and
not docs/guides/: that policy already owns the git mechanics, and its §6 was the thing prescribing
the clone-per-task recipe. Fixing it in place beats adding a fourth description of upstream process.
§6 keeps both footguns, since the cost is unrecoverable and the symptoms do not read as "shallow",
and now says what prevents them. Numbering starts at §0 deliberately: upstream-occt-style.md links
to #2-add-a-gtest-in-the-same-commit and #4-format, and renumbering would silently break both.

Also corrected as docs-current fallout: Scripts/patches/README.md's 0018 entry still called the
reply "drafted" and named #1417 as the live PR, and its 0019 entry did not record that #1418 is
merged upstream (07e6d8d40). 0019 stays carried, since no OCCT release contains it yet.

CHANGELOG entry

Upstream OCCT work moves to a persistent branch checkout of our fork (#803)

Process and documentation only, no library change. Upstream patches are now developed in one
persistent blobless checkout of gsdali/OCCT with Open-Cascade-SAS/OCCT as a second remote, shared
across worktrees, instead of a shallow clone created per task and discarded. The old pattern is what
closed OCCT#1417 (a git commit --amend
against a --depth 1 clone produces a rootless commit, and GitHub closes the PR as unrelated history
with no way to reopen it); that PR was reopened as
OCCT#1457. Documented as §0 of
okf/policies/upstream-occt-patch-process.md. The four upstream replies and test files staged under
Scripts/repro/*/upstream/ now each carry a status header recording whether they were sent, so a
file that was posted no longer reads as a pending draft.

SemVer impact

NONE. No source, no public API, no behaviour. The diff is one okf policy, two reproducer READMEs,
Scripts/patches/README.md, and four staged upstream artifacts under Scripts/repro/*/upstream/.
Nothing a consumer compiles against is touched, and the next release is v3.0.0 for reasons unrelated
to this PR (#844's rename, already in ## Unreleased).

Checklist

  • New or changed behavior is covered by a unit test in the same PR. Not applicable, no code
    changes: no test exists that could observe this diff.
  • Every new test and every new --self-test case was run once with its subject broken. Not
    applicable, no new tests. Every existing gate self-test was run and passes, listed below.
  • The CHANGELOG entry above is complete, and docs/CHANGELOG.md is not in this diff.
  • The SemVer impact above is stated, and docs/SEMVER.md is not in this diff.

Notes for the reviewer

Gate scripts, all green (run from the repo root):

check-bridge-index.py             0 stale, 0 misfiled           + --self-test 18/18
check-null-handle-guards.py       all guarded                   + --self-test 24/24
check-docs-defaults.py            0 drifted                     + --self-test 13/13
check-docs-existence.py           0 stale                       + --self-test 27/27
derive-bridge-header-split.py     0 ambiguous/unmapped/misfiled  + --self-test 8/8
count-operations.py               4339, README and API_REFERENCE both agree
census-unmeasured-values.py       --self-test 36/36
check-changelog-transcription.py  --self-test 23/23; the real run lists 12 pre-existing gaps from
                                  other merges, none from this branch
no conflict markers               clean
file-size-check.py                unchanged, no Swift touched

No swift build / swift test run: the diff contains no Swift, no .mm, no .h, and no
Package.swift.

Em-dash cleanup, and where it stops. writing-style.md asks for em-dashes to be cleared from any
file being edited. Done for okf/policies/upstream-occt-patch-process.md (14, plus one banned
"honest") and Scripts/repro/522-approx-c0-collapse/README.md (16). Not done for
Scripts/patches/README.md, which has 144 across 1164 lines: that is the dedicated pass the policy
explicitly does not require, and it would bury a two-sentence status correction under an unrelated
rewrite of the kernel-patch evidence record. Flagging the choice rather than leaving it to be
noticed.

The bodies of the staged replies are deliberately unedited, including their em-dashes. The 555
one is a verbatim copy of a public comment and the header claims byte-identity, which was re-verified
after adding the header. Editing either body would falsify the record.

Left undone, deliberately. The staged Draw test tests/bugs/moddata_3/bug1418 was never
contributed and #1418 merged without it. Sending it now means a fresh PR against a merged fix, which
is a call for the user, not something to do under a "post the staged replies" issue. The file says so
at the top.

Scripts/repro/657-upstream-pr-status/ describes a disposable sparse clone as its Method 2. Left
alone: it is a dated audit artifact recording how that audit was performed, not a live prescription,
and the persistent checkout now answers the same question without cloning.

…tern

Two pieces of upstream housekeeping deferred past v2.0.0.

The staged replies are settled on evidence rather than on what #803 assumed.
OCCT#1418 merged on 2026-08-10 without its reply, its rewritten description or
its Draw test; OCCT#1417 was closed by an amend against a shallow clone and
reopened as OCCT#1457, where the #555 reply was posted the same day, byte for
byte below its scaffolding. All four staged files now carry a status header
saying which of those happened to them, so none of them reads as a pending
draft when it was sent, or as sendable when it is moot. Nothing is owed
upstream: a sweep of all fifteen open PRs finds no maintainer comment left
unanswered.

The workflow change is the remaining work. Upstream branches now live in one
persistent blobless checkout of gsdali/OCCT with Open-Cascade-SAS/OCCT as a
second remote, shared across worktrees, rather than a shallow clone made per
task. That clone is what closed OCCT#1417, and it is not recoverable. §0 of
okf/policies/upstream-occt-patch-process.md documents it, and §6 keeps the two
footguns as the reason it exists.

Libraries/occt-src was evaluated as the host and rejected on four measured
counts, the strongest being that build-occt.sh reuses it only when HEAD is
exactly at the pinned tag and prints `rm -rf occt-src` when it is not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gsdali
gsdali merged commit 0763cde into main Aug 17, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Post-release: post the two staged upstream replies, and move to branch checkouts of our own fork

1 participant