Skip to content

Fix checkout init for SHA-256 repositories#2439

Draft
yaananth wants to merge 1 commit into
mainfrom
fix-sha256-init-5528
Draft

Fix checkout init for SHA-256 repositories#2439
yaananth wants to merge 1 commit into
mainfrom
fix-sha256-init-5528

Conversation

@yaananth
Copy link
Copy Markdown
Contributor

@yaananth yaananth commented May 21, 2026

Summary

Fixes github/actions-runtime#5528 by initializing checkout's local Git repository with the object format used by the target repository.

SHA-256 repositories fail today because checkout creates the local repository with plain git init before fetching. Plain git init creates a SHA-1 repository by default, so the later fetch from a SHA-256 remote fails with a client/server object-format mismatch unless the workflow manually sets GIT_DEFAULT_HASH=sha256.

This PR updates checkout to:

  • determine the target repository object format before git init
  • use an existing commit SHA directly when checkout already has one
  • otherwise use the existing authenticated GitHub API path to infer the format from a branch commit SHA
  • reuse the default branch value from object-format detection when checkout later needs it
  • use git ls-remote --symref HEAD when the API path cannot identify the format and the remote can advertise HEAD directly
  • run git init --object-format=sha256 only when the repository is positively identified as SHA-256
  • preserve checkout's existing default git init behavior for SHA-1 repositories and for cases where the format is not identified

Why this approach

Checkout has to choose the local repository object format before the first fetch. The GitHub API path already uses the action token and works before a .git directory exists, so it supports private repositories without setting up Git credential config early.

The request count depends on the information checkout already has:

  • when checkout already has a commit SHA, no API request is needed for object-format detection
  • when checkout has a branch ref, detection uses the branch endpoint for that branch's commit SHA
  • when checkout has no ref or commit, detection uses the repository endpoint to read default_branch, then the branch endpoint for that branch's commit SHA; the resolved default branch is reused later in the checkout flow

For the hash algorithms handled here, a 40-character commit object ID is SHA-1 and a 64-character commit object ID is SHA-256.

The direct Git probe covers repositories where the API lookup is unavailable but HEAD is advertised normally. Checkout only opts into SHA-256 initialization after a positive SHA-256 result; otherwise it preserves the existing initialization path.

Security notes

The pre-init detection uses the existing Octokit/API authentication path and does not require writing Git credentials before repository initialization. Normal checkout authentication still happens through the existing auth helper flow, including the existing cleanup behavior for persist-credentials: false.

Validation

  • npm run build
  • npm test -- --runInBand
  • npm run format-check
  • npm run lint
  • built-action smoke checkout of a SHA-256 repository verified the resulting local repository uses sha256
  • authenticated built-action smoke checkout with persist-credentials: false verified checkout succeeds and leaves no local auth config or temporary credential file behind

@yaananth yaananth force-pushed the fix-sha256-init-5528 branch from f279b42 to 67bd696 Compare May 21, 2026 20:56
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.

1 participant