# What is Sparse Checkout in actions/checkout and How It Optimizes Large Repositories

> Learn how sparse checkout in actions/checkout optimizes large repositories by downloading only necessary files. Reduce clone time, network transfer, and disk usage.

- Repository: [GitHub Actions/checkout](https://github.com/actions/checkout)
- Tags: deep-dive
- Published: 2026-08-29

---

**Sparse checkout in `actions/checkout` is a feature that downloads only specific directories or files from a repository instead of the entire codebase, dramatically reducing clone time, network transfer, and disk usage for large monorepos.**

The `actions/checkout` GitHub Action implements Git's native sparse-checkout capability (available from Git 2.28 onward) to let workflows materialize only the portions of a repository required for a specific job. By avoiding full tree downloads, this optimization is essential for CI pipelines dealing with monorepos containing multiple unrelated projects or extensive legacy codebases.

## How Sparse Checkout Works in actions/checkout

The implementation spans three core TypeScript modules that handle input parsing, orchestration, and low-level Git execution. When you specify the `sparse-checkout` input, the action intercepts the standard clone process and configures Git to operate in partial tree mode.

### Input Parsing and Configuration

In [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts) (lines 112-119), the action reads the `sparse-checkout` and `sparse-checkout-cone-mode` inputs from the workflow definition. It populates a `GitSourceSettings` object with a `sparseCheckout` array containing the requested paths and a boolean flag for `sparseCheckoutConeMode`. This configuration determines whether the action uses Git's modern cone mode (optimized for directory-level granularity) or falls back to the legacy pattern-based sparse checkout.

### Git Command Orchestration

The [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) module (lines 184-265) contains the decision logic for invoking sparse checkout. When `settings.sparseCheckout` is present, the action creates a dedicated log group labeled "Setting up sparse checkout" before executing the initialization sequence. This module handles the lazy fetch strategy: it enables sparse-checkout configuration first, then runs `git checkout` to materialize only the requested paths, allowing Git to fetch additional objects on demand if subsequent workflow steps require them.

### Low-Level Git Implementation

Actual Git commands are abstracted in [`src/git-command-manager.ts`](https://github.com/actions/checkout/blob/main/src/git-command-manager.ts). For cone mode (lines 202-219), the action executes `git sparse-checkout set <paths>` to configure the partial tree. For non-cone mode, it manually writes patterns to `.git/info/sparse-checkout` and toggles the `core.sparseCheckout` configuration. The module includes a version guard at line 732 that validates the runner's Git version is 2.28 or higher, throwing a clear error if the environment does not support sparse checkout.

## Performance Benefits for Large Repositories

Sparse checkout delivers measurable optimizations for CI workflows through four primary mechanisms:

- **Reduced network traffic**: Only Git objects required for explicitly listed paths are retrieved from the remote, minimizing data transfer over the network.
- **Faster clone operations**: By limiting tree checkout to a subset of directories, Git completes the clone in a fraction of the time required for full repository downloads.
- **Lower disk utilization**: Only selected files are written to the runner's workspace, conserving storage for subsequent build steps and caching operations.
- **Improved cache efficiency**: When sparse paths remain consistent across workflow runs, Git-LFS and action caches hit more frequently, further accelerating build times.

## Implementation Requirements and Constraints

Sparse checkout requires **Git 2.28 or later** on the runner. The [`src/git-command-manager.ts`](https://github.com/actions/checkout/blob/main/src/git-command-manager.ts) file enforces this requirement with an explicit version check. If your workflow runs on older Git versions, the action will fail with a descriptive error message indicating the version incompatibility.

When using Git LFS, the action automatically disables LFS downloads for sparse checkouts unless explicitly enabled via the `lfs: true` input. This prevents unnecessary large-file transfers for assets located outside the sparse checkout paths.

## Configuring Sparse Checkout in Your Workflows

You can enable sparse checkout by adding the `sparse-checkout` input to your workflow step. The action supports both cone mode (default, directory-based) and non-cone mode (pattern-based) configurations.

### Basic Cone Mode Configuration

Cone mode is the default and recommended approach for most use cases, providing optimal performance when you need specific top-level directories:

```yaml
steps:
  - uses: actions/checkout@v4
    with:
      sparse-checkout: |
        packages/core
        docs

```

In this configuration, [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts) parses the multiline input into an array, and [`src/git-command-manager.ts`](https://github.com/actions/checkout/blob/main/src/git-command-manager.ts) executes `git sparse-checkout set packages/core docs`. Only the `packages/core` and `docs` directories materialize in the workspace.

### Non-Cone Mode for Complex Patterns

For advanced use cases requiring glob patterns or file-level granularity, disable cone mode:

```yaml
steps:
  - uses: actions/checkout@v4
    with:
      sparse-checkout: |
        /src/**/*.java
        /resources/*.xml
      sparse-checkout-cone-mode: false

```

With cone mode disabled, the action writes the patterns directly to `.git/info/sparse-checkout` and enables `core.sparseCheckout`, supporting full glob syntax that cone mode does not handle.

### Combining with Git LFS

To download large files only for paths within your sparse checkout:

```yaml
steps:
  - uses: actions/checkout@v4
    with:
      sparse-checkout: |
        models/
      lfs: true

```

This configuration limits LFS object retrieval to files actually present in the sparse checkout, preventing full-repository LFS downloads.

### Dynamic Path Configuration

You can compute sparse checkout paths at runtime using environment variables or expressions:

```yaml
env:
  TARGET_DIR: src/services

steps:
  - uses: actions/checkout@v4
    with:
      sparse-checkout: ${{ env.TARGET_DIR }}

```

The action interpolates the variable during [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts) execution, allowing dynamic path selection based on changed files or matrix strategy variables.

## Summary

- **Sparse checkout** in `actions/checkout` leverages Git 2.28+ native capabilities to clone only specified repository paths.
- The implementation flows through [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts) for parsing, [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) for orchestration, and [`src/git-command-manager.ts`](https://github.com/actions/checkout/blob/main/src/git-command-manager.ts) for Git execution.
- **Cone mode** (default) optimizes for directory-level granularity, while **non-cone mode** supports complex glob patterns through `.git/info/sparse-checkout`.
- This feature reduces network transfer, clone time, and disk usage for large monorepos and multi-project repositories.
- Version guards in the source code ensure graceful failures on Git versions older than 2.28.

## Frequently Asked Questions

### What Git version is required for sparse checkout?

Sparse checkout requires **Git 2.28 or later**. The `actions/checkout` action validates the runner's Git version in [`src/git-command-manager.ts`](https://github.com/actions/checkout/blob/main/src/git-command-manager.ts) (line 732) and will fail with a clear error message if the environment runs an older version.

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

**Cone mode** (the default) optimizes for directory-level sparse checkouts using `git sparse-checkout set`, providing better performance and simpler path specifications. **Non-cone mode** writes patterns directly to `.git/info/sparse-checkout` and supports complex globs like `**/*.java`, but with higher configuration overhead and potential performance trade-offs.

### Can I use sparse checkout with Git LFS?

Yes, but LFS is disabled by default for sparse checkouts to prevent downloading large files outside the sparse paths. Set `lfs: true` in your workflow configuration to enable LFS downloads limited to files present within your sparse checkout directories.

### Does sparse checkout affect the Git history?

No, sparse checkout does not modify the repository's history or commit graph. It only affects the working tree and index, determining which files are physically present in the workspace. The full Git object database remains available remotely, and additional paths can be fetched on demand if workflow steps require them.