Skip to content

fix(host-service): bypass user git hooks for scaffolding initial commits - #6320

Merged
saddlepaddle merged 1 commit into
mainfrom
sentry/hs-session-commit-hooks
Aug 13, 2026
Merged

saddlepaddle merged 1 commit into
mainfrom
sentry/hs-session-commit-hooks

Conversation

@Kitenite

@Kitenite Kitenite commented Aug 10, 2026 •

Copy link
Copy Markdown
Member

Problem

Creating a session (workspaces.createSession → initEmptyRepo) initializes a fresh repo under the sessions root and makes a scaffolding "Initial commit". If the user has global git hooks configured (e.g. a core.hooksPath commit-msg hook enforcing a commit-message policy), the hook runs against our scaffolding commit and rejects it — session creation deterministically fails as INTERNAL_SERVER_ERROR for any user with such a hook (2 events on 1.20.0).

Root cause

The scaffolding "Initial commit" invocations in resolve-repo.ts (initEmptyRepo, initLocalRepoInPlace, cloneTemplateInto) run plain git commit, so the user's machine-wide hooks apply to commits we author in repos we just created. asInitialCommitTrpcError types git-user-not-configured but a hook rejection falls through to a 500.

Fix

Run all three scaffolding commits with hooks bypassed: -c core.hooksPath= commit --no-verify. Both parts are needed — --no-verify skips pre-commit/commit-msg, and the empty core.hooksPath override covers hooks --no-verify doesn't (verified empirically: a failing prepare-commit-msg still aborts a --no-verify commit). createUserSimpleGit already enables allowUnsafeHooksPath, so simple-git permits the override.

Decision on the cloneTemplateInto snapshot path (commits the user's template files into a repo we just initialized): bypass there too. The user does not author that commit invocation either, and a rejecting global hook fails template creation identically — same failure mode, same fix.

asInitialCommitTrpcError classification is kept unchanged for what can still fail (git identity not configured, disk errors). No hook-rejection classification was added since the bypass covers every scaffolding path — there is no remaining path where a hook can reject these commits.

Precedent: #6168 (hook tolerance in workspace setup).

Also fixed a latent test-fixture hazard found along the way: simple-git only fails a raw task on non-zero exit when stderr is non-empty, so the regression tests' rejecting hooks print to stderr like real policy hooks do (a silent exit 1 hook is swallowed by simple-git — noted in the test comment).

Verification

bunx biome check on both changed files:

Checked 2 files in 14ms. No fixes applied.

cd packages/host-service && bun run typecheck:

$ tsc --noEmit --emitDeclarationOnly false
(clean exit)

bun test packages/host-service/src/trpc/router/project/utils/resolve-repo.test.ts:

 34 pass
 0 fail
 65 expect() calls
Ran 34 tests across 1 file. [7.00s]

Mutation check — with the bypass reverted to plain git commit, the three new regression tests fail; restored, all 34 pass:

(fail) scaffolding commits bypass user git hooks > initLocalRepoInPlace commits despite rejecting global hooks
(fail) scaffolding commits bypass user git hooks > initEmptyRepo commits despite rejecting global hooks
(fail) scaffolding commits bypass user git hooks > cloneTemplateInto snapshot commit despite rejecting global hooks
 31 pass / 3 fail

Refs HOST-SERVICE-13

https://claude.ai/code/session_1a228bdc-29c4-4d4e-8e63-7bb4acf54aaf


Summary by cubic

Bypass user git hooks for scaffolding “Initial commit” during session repo setup to prevent 500s when global hooks reject commits. Aligns with HOST-SERVICE-13 by ensuring session creation doesn’t depend on user git hook policies.

  • Bug Fixes
    • Run scaffolding commits with -c core.hooksPath= and --no-verify in initEmptyRepo, initLocalRepoInPlace, and cloneTemplateInto.
    • Keep existing error mapping; hooks can no longer block these commits.
    • Add regression tests that simulate rejecting global hooks and ensure simple-git surfaces failures via stderr.

Written for commit 355a72f. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Repository scaffolding now succeeds even when global Git hooks would otherwise reject initial commits.
    • Standard user commits continue to respect and enforce configured Git hooks.
    • Applied consistent hook handling when creating repositories in place, initializing empty repositories, or cloning templates.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1d5cdcbd-0b82-46de-bd66-32620fa50ef0

📥 Commits

Reviewing files that changed from the base of the PR and between 31fb0fc and 355a72f.

📒 Files selected for processing (2)
  • packages/host-service/src/trpc/router/project/utils/resolve-repo.test.ts
  • packages/host-service/src/trpc/router/project/utils/resolve-repo.ts

📝 Walkthrough

Walkthrough

Repository scaffolding now bypasses rejecting global Git hooks for in-place initialization, empty repositories, and template clones. Tests confirm that ordinary commits remain subject to the hooks.

Changes

Scaffold commit hook handling

Layer / File(s) Summary
Hook-bypassing scaffold commit implementation
packages/host-service/src/trpc/router/project/utils/resolve-repo.ts
Shared commit arguments clear core.hooksPath and add --no-verify for all scaffold commit paths.
Global hook integration coverage
packages/host-service/src/trpc/router/project/utils/resolve-repo.test.ts
Tests verify that rejecting global hooks block ordinary commits but allow repository initialization, empty-repository creation, and template cloning.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: saddlepaddle

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title uses conventional commit format and clearly describes bypassing user Git hooks for host-service scaffolding commits.
Description check ✅ Passed The description explains the problem, root cause, fix, testing, and affected paths, but it does not include the template checklist.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sentry/hs-session-commit-hooks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ✅ Neon database branch

Thank you for your contribution! 🎉

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Architecture diagram
sequenceDiagram
    participant UI as Client UI
    participant API as TRPC Router
    participant Workspace as workspaces.createSession
    participant RepoUtils as resolve-repo.ts
    participant Git as SimpleGit (local)
    participant Hooks as User Global Git Hooks
    participant FS as Filesystem

    Note over UI,FS: Session Creation / Repo Scaffolding Flow

    UI->>API: createSession
    API->>Workspace: initialize workspace
    Workspace->>RepoUtils: initEmptyRepo(sessionsRoot, name)

    alt initEmptyRepo path
        RepoUtils->>Git: gitInitMainBranch(targetPath)
        Git->>FS: git init --initial-branch=main
        FS-->>Git: repo initialized
        RepoUtils->>Git: raw(["-c", "core.hooksPath=", "commit", "--no-verify", "--allow-empty", "-m", "Initial commit"])
        Note over Git: Bypasses user hooks via empty hooksPath + --no-verify
        Git->>FS: commit (hooks bypassed)
        FS-->>Git: commit success
        Git-->>RepoUtils: ok
    else initLocalRepoInPlace path
        RepoUtils->>Git: gitInitMainBranch(repoPath)
        Git->>FS: git init --initial-branch=main
        FS-->>Git: repo initialized
        RepoUtils->>Git: raw(["-c", "core.hooksPath=", "commit", "--no-verify", "--allow-empty", "-m", "Initial commit"])
        Note over Git: Same hook bypass applied
        Git->>FS: commit (hooks bypassed)
        FS-->>Git: commit success
        Git-->>RepoUtils: ok
    else cloneTemplateInto path
        RepoUtils->>Git: clone template into targetPath
        Git-->>RepoUtils: repo cloned
        RepoUtils->>Git: add(".")
        Git->>FS: stage files
        FS-->>Git: staged
        RepoUtils->>Git: raw([...scaffoldCommitArgs, "-m", "Initial commit"])
        Note over Git: Bypass covers template snapshot commit too
        Git->>FS: commit (hooks bypassed)
        FS-->>Git: commit success
        Git-->>RepoUtils: ok
    end

    alt hook bypass succeeds
        RepoUtils-->>Workspace: resolved repo path
        Workspace-->>API: session created
        API-->>UI: success response
    else git identity or disk error
        RepoUtils->>RepoUtils: asInitialCommitTrpcError(err)
        RepoUtils-->>Workspace: TRPCError
        Workspace-->>API: error
        API-->>UI: error response (500/400)
    end

    Note over Git,Hooks: User global hooks are never triggered for scaffolding commits
    Note over Git: createUserSimpleGit already allowsUnsafeHooksPath, enabling the override
Loading

Re-trigger cubic

@saddlepaddle
saddlepaddle merged commit 3e6392b into main Aug 13, 2026
19 checks passed
@saddlepaddle
saddlepaddle deleted the sentry/hs-session-commit-hooks branch August 13, 2026 18:39

This branch was previously deployed

1 inactive deployment
preview — 355a72f4 Deployed Aug 10, 2026 by Kitenite via Deploy Admin #7371
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.

2 participants