How actions/checkout Implements Sparse Checkout: Git Commands and Architecture

The actions/checkout action implements sparse checkout by reading the sparse-checkout and sparse-checkout-cone-mode inputs in src/input-helper.ts, storing them in GitSourceSettings, then executing either git sparse-checkout set or legacy file-based sparse checkout through src/git-command-manager.ts after the initial clone.

The actions/checkout GitHub Action provides native support for sparse checkout, allowing CI/CD pipelines to fetch only specific directories rather than entire repositories. This optimization reduces checkout time and disk usage by leveraging Git's sparse-checkout capabilities (requires Git 2.28+). The implementation coordinates four TypeScript modules to parse inputs, store configuration, and execute the appropriate Git commands.

Input Handling and Configuration Storage

The sparse checkout feature begins with input parsing and type-safe configuration storage.

Parsing Workflow Inputs in src/input-helper.ts

The src/input-helper.ts module reads the workflow configuration and populates the settings object. It specifically looks for the multiline sparse-checkout input, which accepts a list of directories or files to include. It also reads the optional boolean sparse-checkout-cone-mode flag, which defaults to true for modern cone-mode behavior.

The GitSourceSettings Interface in src/git-source-settings.ts

The src/git-source-settings.ts file defines the data model that carries configuration through the checkout pipeline. It extends the base settings with two critical fields: sparseCheckout: string[] to store the path list, and sparseCheckoutConeMode: boolean to determine the execution strategy. These properties enable downstream modules to determine whether and how to configure sparse checkout.

Execution Flow and Git Integration

After the repository clones, the provider decides whether to enable sparse checkout based on the populated settings.

Orchestrating Checkout in src/git-source-provider.ts

The src/git-source-provider.ts module contains the decision logic that triggers sparse checkout. After completing the initial clone, it checks if (settings.sparseCheckout) to determine if path filtering is required. When enabled, it opens a log group labeled "Setting up sparse checkout" and branches based on settings.sparseCheckoutConeMode. For cone mode, it invokes git.sparseCheckout(); otherwise, it calls git.sparseCheckoutNonConeMode() to handle legacy repositories.

Git Command Wrappers in src/git-command-manager.ts

The src/git-command-manager.ts module abstracts the actual Git invocations. The sparseCheckout() method executes git sparse-checkout set <paths> using Git's native cone-mode implementation available in Git 2.28 and later. The sparseCheckoutNonConeMode() method instead writes the .git/info/sparse-checkout file directly and sets the core.sparseCheckout configuration to true, supporting older Git behaviors. Both methods ensure the working directory contains only the specified paths after execution.

Configuring Sparse Checkout in Workflows

Implementing sparse checkout requires specific YAML syntax to pass the path list correctly.

Cone mode (default) uses the modern git sparse-checkout command:

- uses: actions/checkout@v4
  with:
    sparse-checkout: |
      src/
      docs/
      package.json

Non-cone mode for edge cases or legacy pattern matching:

- uses: actions/checkout@v4
  with:
    sparse-checkout: |
      legacy/path/
    sparse-checkout-cone-mode: false

Version Requirements and Edge Cases

The action includes safeguards for compatibility and complex repository states.

Git version 2.28 is the minimum required for the native sparse-checkout commands used in cone mode. When sparse checkout is enabled alongside Git LFS, the action defers LFS fetching because sparse checkout populates files lazily. The implementation also handles shallow clones and pre-existing repository states by skipping sparse-checkout setup when the repository configuration indicates it would conflict with the current state.

Summary

  • Input Parsing: The src/input-helper.ts module captures the sparse-checkout path list and cone-mode flag from workflow definitions.
  • Configuration Storage: src/git-source-settings.ts transports these values as sparseCheckout and sparseCheckoutConeMode properties through the checkout pipeline.
  • Execution Logic: src/git-source-provider.ts decides post-clone whether to invoke sparse checkout based on the presence of path constraints.
  • Git Abstraction: src/git-command-manager.ts executes git sparse-checkout set for cone mode or writes the info/sparse-checkout file for legacy non-cone mode.
  • Requirements: Git 2.28+ is required, and the action handles LFS interactions by deferring smudge operations when sparse checkout is active.

Frequently Asked Questions

What Git version is required for sparse checkout in actions/checkout?

Sparse checkout requires Git 2.28 or later when using the default cone mode, as this version introduced the git sparse-checkout command. The action validates the Git version before attempting to execute sparse checkout commands and provides clear error messages for older versions.

How do I check out multiple directories using the sparse-checkout input?

Provide a multiline string to the sparse-checkout parameter listing each directory or file on its own line. The src/input-helper.ts module parses this input into an array of paths that are passed to the Git sparse-checkout command.

What is the difference between cone mode and non-cone mode?

Cone mode uses the native git sparse-checkout set command available in Git 2.28+, offering better performance and simpler pattern matching for directories. Non-cone mode writes the .git/info/sparse-checkout file directly and relies on the older core.sparseCheckout configuration, which the action implements in git-command-manager.ts for compatibility with complex pattern rules in legacy repository structures.

Does sparse checkout work with Git LFS in actions/checkout?

Yes, but with modified behavior. When sparse checkout is enabled, the action defers LFS object fetching because sparse checkout populates files lazily. This prevents unnecessary LFS downloads for files outside the sparse checkout boundaries, optimizing both network usage and storage.

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 →