# When Is Non-Cone Mode Required for Sparse Checkout in actions/checkout

> Discover when to use non-cone mode for sparse checkout in actions/checkout. Learn to checkout specific files, use advanced patterns, or support older Git versions.

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

---

**Set `sparse-checkout-cone-mode: false` when you need to checkout individual files, use glob-style or negative patterns, exclude the repository root from the working tree, or support Git versions older than 2.25.**

The `actions/checkout` action supports **sparse checkout** to clone only specific portions of a repository, reducing bandwidth and storage overhead. While the default cone mode efficiently handles directory prefixes, certain advanced filtering scenarios require disabling it to use the classic implementation that accepts arbitrary path patterns.

## Understanding Cone Mode vs Non-Cone Mode

`actions/checkout` implements two distinct sparse checkout algorithms:

- **Cone mode** (default): Uses the Git 2.25+ "cone-mode" algorithm. It only accepts **directory prefixes** (e.g., `src/`, `docs/`). This mode is optimized for performance and simplicity.
- **Non-cone (classic) mode**: Falls back to the older `core.sparseCheckout` implementation. It accepts **arbitrary path patterns**, including single files, glob-style patterns, and negative patterns.

The action determines which mode to use via the `sparse-checkout-cone-mode` input, which defaults to `true`.

## When Non-Cone Mode Is Required

You must explicitly set `sparse-checkout-cone-mode: false` in the following scenarios:

### Checking Out Individual Files

Cone mode strictly requires directory prefixes. If your workflow needs to fetch only specific files—such as [`README.md`](https://github.com/actions/checkout/blob/main/README.md) or `LICENSE`—without their parent directories, non-cone mode is mandatory.

In [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts), the action branches based on this flag:

```typescript
if (settings.sparseCheckoutConeMode) {
  await git.sparseCheckout(settings.sparseCheckout)
} else {
  await git.sparseCheckoutNonConeMode(settings.sparseCheckout)
}

```

(Source: [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts), lines 61-65)

### Complex Pattern Matching

Non-cone mode supports advanced pattern syntax that cone mode rejects:

- **Glob patterns**: Wildcards like `src/**/*.test.ts`
- **Negative patterns**: Exclusions like `!docs/internal/`

These patterns rely on the classic `core.sparseCheckout` configuration rather than the cone algorithm's simplified prefix matching.

### Excluding the Repository Root

If you require a working tree where the repository root directory remains empty except for explicitly listed paths, non-cone mode is required. The test suite in [`__test__/verify-sparse-checkout-non-cone-mode.sh`](https://github.com/actions/checkout/blob/main/__test__/verify-sparse-checkout-non-cone-mode.sh) validates this behavior, verifying that root files do not exist when non-cone mode is active:

```bash
ENABLED=$(git config --local --get-all core.sparseCheckout)
if [ "$ENABLED" != "true" ]; then
  echo "Expected sparse-checkout to be enabled (is: $ENABLED)"
  exit 1
fi

# ... verify listed directories exist, root files do NOT exist ...

```

(Source: [`__test__/verify-sparse-checkout-non-cone-mode.sh`](https://github.com/actions/checkout/blob/main/__test__/verify-sparse-checkout-non-cone-mode.sh), lines 12-23)

### Legacy Git Compatibility

Cone mode requires Git 2.25 or later. Workflows running on self-hosted runners with older Git installations must use non-cone mode to perform any sparse checkout.

## How the Action Determines the Mode

The flag parsing occurs in [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts):

```typescript
result.sparseCheckoutConeMode =
  (core.getInput('sparse-checkout-cone-mode') || 'true').toUpperCase() === 'TRUE'

```

(Source: [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts), lines 118-120)

When `sparseCheckoutConeMode` is `false`, the action invokes `git.sparseCheckoutNonConeMode()` from [`src/git-command-manager.ts`](https://github.com/actions/checkout/blob/main/src/git-command-manager.ts), configuring `core.sparseCheckout` to `true` and writing patterns directly to `.git/info/sparse-checkout` without the cone algorithm's restrictions.

## Configuration Examples

### Sparse Checkout of a Single File

This example checks out only [`README.md`](https://github.com/actions/checkout/blob/main/README.md), leaving the root folder otherwise empty:

```yaml
steps:
  - uses: actions/checkout@v7
    with:
      sparse-checkout: |
        README.md
      sparse-checkout-cone-mode: false

```

*Result*: Only [`README.md`](https://github.com/actions/checkout/blob/main/README.md) is present in the working directory.

### Mixed Directories and Files

To checkout both directories and individual files simultaneously:

```yaml
steps:
  - uses: actions/checkout@v7
    with:
      sparse-checkout: |
        src
        docs
        LICENSE
      sparse-checkout-cone-mode: false

```

*Result*: The `src/` and `docs/` directories are fully checked out, plus the `LICENSE` file. Non-prefix patterns (the file) are allowed only in non-cone mode.

### Default Cone Mode for Directory Prefixes

For comparison, the default cone mode works efficiently with directory-only patterns:

```yaml
steps:
  - uses: actions/checkout@v7
    with:
      sparse-checkout: |
        src
        docs

```

*Result*: Fast checkout of the two directories. Any non-directory pattern would be rejected or behave unpredictably.

## Summary

- **Cone mode** (default) accepts only directory prefixes and requires Git 2.25+—use it for simple folder-based sparse checkouts.
- **Non-cone mode** is required for individual files, glob patterns, negative patterns, or excluding the repository root.
- Set `sparse-checkout-cone-mode: false` to enable the classic `core.sparseCheckout` implementation.
- The action implements this logic in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) and [`src/git-command-manager.ts`](https://github.com/actions/checkout/blob/main/src/git-command-manager.ts), with input parsing handled in [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts).

## Frequently Asked Questions

### Can I use glob patterns like `**/*.md` in sparse checkout?

**Yes, but only in non-cone mode.** Cone mode strictly interprets sparse checkout patterns as directory prefixes. To use glob patterns, wildcards, or file-level filtering, you must set `sparse-checkout-cone-mode: false` according to the `actions/checkout` source code implementation.

### Why is single file checkout failing with cone mode enabled?

Cone mode only recognizes directory paths, not individual files. When you specify a file path like [`README.md`](https://github.com/actions/checkout/blob/main/README.md) with the default `sparse-checkout-cone-mode: true`, Git treats it as a directory prefix that doesn't exist. Disable cone mode to checkout specific files.

### Does non-cone mode work with all Git versions?

Non-cone mode has broader compatibility than cone mode. While cone mode requires Git 2.25 or later, the classic `core.sparseCheckout` implementation used in non-cone mode works with significantly older Git versions, making it necessary for legacy self-hosted runner environments.

### How can I verify that non-cone mode is working correctly?

The action's test suite uses [`__test__/verify-sparse-checkout-non-cone-mode.sh`](https://github.com/actions/checkout/blob/main/__test__/verify-sparse-checkout-non-cone-mode.sh) to validate behavior. You can verify manually by checking that `git config --local --get-all core.sparseCheckout` returns `true` and confirming that root files are absent while only your specified paths are present in the working tree.