How the Filter Option Enables Partial Clone in actions/checkout

The filter input enables partial clone by passing the --filter flag to Git's fetch command, allowing workflows to omit specific object types like blobs or trees to reduce data transfer and storage.

The actions/checkout GitHub Action exposes Git's partial clone functionality through the filter input, which controls precisely which repository objects are downloaded from the remote. By leveraging filters such as blob:none or tree:0, CI/CD pipelines can significantly reduce network overhead and disk consumption when working with large monorepos. This article examines the source code implementation to explain how the action translates YAML configuration into Git's native filtering capabilities.

Input Processing and Validation

The implementation flows through three critical TypeScript modules that transform the user-provided filter value into a command-line argument for the underlying Git process.

Reading the Input in input-helper.ts

In src/input-helper.ts, the action retrieves the optional filter input using the @actions/core library and conditionally adds it to the result settings object.

const filter = core.getInput('filter')
if (filter) {
  result.filter = filter
}

This logic ensures that only explicitly provided filter values are propagated through the system, maintaining backward compatibility for workflows that do not require partial clone functionality.

Configuring Fetch Options in git-source-provider.ts

In src/git-source-provider.ts, the code maps the filter setting to the fetchOptions object passed to the Git command manager. A key implementation detail is the automatic fallback to blob:none when sparse-checkout is enabled without an explicit filter.

if (settings.filter) {
  fetchOptions.filter = settings.filter
} else if (settings.sparseCheckout) {
  fetchOptions.filter = 'blob:none'
}

This fallback prevents unnecessary blob downloads when the workflow only requires a subset of the repository's files, optimizing both network usage and storage.

Constructing the Git Command in git-command-manager.ts

Finally, in src/git-command-manager.ts, the GitCommandManager.fetch method constructs the argument array for the git fetch command. When a filter option is present, it pushes the --filter flag with the specified value.

if (options.filter) {
  args.push(`--filter=${options.filter}`)
}

This direct mapping allows the action to support any valid Git filter specification that the underlying Git version supports, without requiring changes to the action code when Git introduces new filter types.

Practical Usage Examples

The filter option accepts any string value recognized by Git's --filter syntax. Here are common patterns for optimizing checkout performance.

Implicit Filter with Sparse Checkout

When using sparse-checkout without an explicit filter, the action automatically applies blob:none to skip downloading file contents outside the sparse paths.

steps:
  - uses: actions/checkout@v4
    with:
      sparse-checkout: |
        src/
        README.md

Explicit Custom Filters

You can specify custom filters to control exactly which Git objects are fetched. The tree:0 option downloads only commit objects and refs, excluding all directories and file contents.

steps:
  - uses: actions/checkout@v4
    with:
      filter: 'tree:0'

Combining with Shallow Clones

For maximum efficiency in CI environments, combine the filter option with fetch-depth to create minimal clones that contain only the latest commit metadata.

steps:
  - uses: actions/checkout@v4
    with:
      fetch-depth: 1
      filter: 'blob:none'

Summary

  • The filter input in actions/checkout passes the --filter flag to the underlying git fetch command
  • Implementation spans three files: src/input-helper.ts, src/git-source-provider.ts, and src/git-command-manager.ts
  • When sparse-checkout is enabled without an explicit filter, the action defaults to blob:none automatically
  • Supports standard Git filter specifications including blob:none, tree:0, and size-based filters
  • Reduces CI/CD pipeline execution time and storage requirements for large repositories

Frequently Asked Questions

What is the difference between filter and sparse-checkout?

Sparse-checkout controls which files appear in your working directory by modifying the .git/info/sparse-checkout file, while the filter option controls which objects are physically downloaded from the remote repository. When using sparse-checkout without an explicit filter, actions/checkout automatically sets filter: blob:none to avoid downloading file contents outside the sparse paths, optimizing both network and storage usage.

Can I use multiple filter values in one checkout step?

Git's partial clone implementation accepts only one filter specification at a time through the --filter flag. You cannot combine blob:none with tree:0 simultaneously in a single fetch operation. However, you can select the most restrictive single filter that meets your workflow requirements, or perform multiple checkout steps with different filters if necessary.

Does the filter option work with all Git providers?

Partial clone requires Git version 2.27 or later on the client side and server-side support for the filter capability. While major hosting providers like GitHub, GitLab, and Bitbucket support this feature, older on-premises Git servers or those with custom configurations may reject the --filter flag, causing the fetch operation to fail.

How does filter: blob:none affect subsequent git operations?

With blob:none, file contents are excluded from the initial fetch and downloaded on-demand when accessed (lazy loading). This means subsequent commands like git checkout, git show, or git diff may trigger additional network requests to fetch missing blobs, which could impact performance if your workflow frequently accesses files outside the initial sparse definition.

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 →