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 createCommandManager in src/git-command-manager.ts before 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 undefined from the error handler signals getSource to switch to the REST API download path.
  • The githubApiHelper.downloadRepository function in src/github-api-helper.ts fetches 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →