How actions/checkout Falls Back to the REST API When Git Is Unavailable
When Git is not installed or is older than version 2.18, the actions/checkout action automatically detects the missing binary and downloads the repository archive via the GitHub REST API instead.
The actions/checkout action is the standard way to clone repositories in GitHub Actions workflows. While it prefers using the native Git client for full functionality, it implements a robust fallback mechanism that allows it to function in environments where Git is unavailable or outdated, such as minimal containers or specialized runners.
The Detection Mechanism in git-command-manager.ts
The action first attempts to instantiate a Git command manager to handle repository operations. This initialization serves as the primary probe for Git availability.
Creating the Git Command Manager
In src/git-command-manager.ts, the createCommandManager function attempts to locate the Git executable and verify its version. If the binary is missing or fails the version check (minimum 2.18), the function throws an error.
// src/git-source-provider.ts
try {
return await gitCommandManager.createCommandManager(
settings.repositoryPath,
settings.lfs,
settings.sparseCheckout != null
)
} catch (err) {
// Git is required for LFS
if (settings.lfs) { throw err }
// Otherwise fallback to REST API
return undefined // ← fallback trigger
}
The Minimum Version Constraint
The git-command-manager.ts file defines the minimum required Git version as 2.18. When this requirement is not met, the creation promise rejects, triggering the catch block in the orchestration layer.
The Fallback Logic in git-source-provider.ts
The getSource function in src/git-source-provider.ts orchestrates the checkout process and handles the transition from Git-based operations to REST API downloads.
Returning Undefined on Failure
When createCommandManager throws and LFS is not requested, the catch block returns undefined instead of propagating the error. This specific return value signals to the rest of the pipeline that Git is unavailable and REST API fallback should commence. Note that if LFS (Large File Storage) is enabled, the action aborts immediately since the REST API cannot handle LFS objects.
Validating Unsupported Features
Before executing the fallback, the code validates that no Git-specific features were requested. When using the REST API path, the action cannot support submodules or ssh-key inputs. The code checks for these configurations and throws descriptive errors if they are present.
// src/git-source-provider.ts
if (!git) {
core.info(`The repository will be downloaded using the GitHub REST API`)
// … unsupported‑input checks …
await githubApiHelper.downloadRepository(
settings.authToken,
settings.repositoryOwner,
settings.repositoryName,
settings.ref,
settings.commit,
settings.repositoryPath,
settings.githubServerUrl
)
return
}
Downloading via the GitHub REST API
When the undefined Git value triggers the fallback path, the action delegates to src/github-api-helper.ts to retrieve the repository contents.
The githubApiHelper.downloadRepository Method
The downloadRepository function constructs a request to the GitHub REST API to fetch the repository archive for the specific commit or ref. It authenticates using the provided token, downloads the tarball or zipball, and extracts it to the designated workspace path. This method bypasses the need for Git history manipulation, providing a shallow copy of the repository at the exact state requested.
Workflow Configuration and Behavior
The README.md documents that the action requires Git version 2.18 or higher in the PATH. When this requirement is not satisfied, the automatic fallback ensures workflows continue without manual intervention.
# Example workflow demonstrating the fallback behavior
jobs:
checkout-without-git:
runs-on: ubuntu-latest
container: alpine:latest # Minimal container without Git
steps:
- uses: actions/checkout@v4
with:
repository: owner/repo
ref: main
# The action detects missing Git and downloads via REST API
Summary
- actions/checkout attempts to create a Git command manager via
createCommandManagerinsrc/git-command-manager.tsbefore starting the checkout process. - If Git is missing or version 2.18+, the creation throws an error that gets caught in
src/git-source-provider.ts. - The fallback only proceeds if LFS is not enabled; otherwise, the action fails immediately.
- Returning
undefinedfrom the error handler signalsgetSourceto switch to the REST API download path. - The
githubApiHelper.downloadRepositoryfunction insrc/github-api-helper.tsfetches the repository archive via the GitHub REST API. - Certain features like submodules and SSH keys are incompatible with the REST API fallback and will cause the action to fail if requested.
Frequently Asked Questions
What happens if Git LFS is requested but Git is not available?
If lfs: true is configured in the workflow but Git cannot be found, the action throws an error and fails immediately. The REST API fallback cannot handle Large File Storage objects, so the action aborts rather than providing an incomplete repository.
Can I use submodules with the REST API fallback?
No. When actions/checkout falls back to the REST API, it cannot fetch submodules. The code explicitly checks for submodules input during the fallback validation and throws an error if this feature is requested without Git available.
Does the REST API fallback preserve Git history?
No. The REST API downloads the repository as a compressed archive (tarball/zipball) of the specific commit or ref, resulting in a shallow copy without full Git history. This is functionally equivalent to a download rather than a clone.
Which Git version is required to avoid the fallback?
Git version 2.18 or higher must be available in the PATH. If the detected version is older or the binary is missing, the action automatically triggers the REST API fallback path as documented in the README.md.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →