How actions/checkout Handles Git LFS: Configuration, Performance, and Implementation

actions/checkout treats Git Large File Storage (LFS) as an opt-in feature controlled by the lfs input, automatically setting GIT_LFS_SKIP_SMUDGE=1 when disabled to prevent downloads, and explicitly running git lfs install and git lfs fetch when enabled to retrieve binary objects.

The actions/checkout repository provides the official GitHub Action for cloning repositories into workflow runners, including specialized handling for repositories using Git LFS to version large binary files. Understanding how this action manages LFS configuration—from input parsing to environment variable injection—helps optimize both workflow performance and network usage. This guide examines the TypeScript source code to explain the complete LFS implementation pipeline.

Parsing the LFS Input Configuration

The journey begins with input validation. In [src/input-helper.ts](https://github.com/actions/checkout/blob/main/src/input-helper.ts#L139-L141), the action reads the boolean lfs input from the workflow YAML. If the user specifies lfs: true, the parsed result sets result.lfs to true; otherwise, it defaults to false. This boolean flag propagates through the entire checkout process, determining whether the action prepares the environment for large file handling.

Disabling LFS Smudge for Performance

When LFS is disabled (the default), the action prioritizes speed and bandwidth conservation.

GIT_LFS_SKIP_SMUDGE Environment Variable

In [src/git-command-manager.ts](https://github.com/actions/checkout/blob/main/src/git-command-manager.ts#L669-L675), the constructor receives the lfs flag. When this value is false, the manager immediately sets the environment variable GIT_LFS_SKIP_SMUDGE=1. This prevents Git from automatically downloading LFS objects during the checkout phase, ensuring that pointer files remain as small text references rather than triggering expensive network fetches for binary data.

Installing and Fetching LFS Objects

When the user explicitly enables LFS, the action shifts to active LFS management through a three-stage process controlled by [src/git-source-provider.ts](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts).

LFS Installation Process

If lfs is true, the provider invokes await git.lfsInstall() during the setup phase (lines 69-73). Before proceeding, the command manager validates that the installed git-lfs binary meets the minimum version requirement of 2.1 or higher, ensuring compatibility with modern LFS features and security patches.

Fetching LFS Objects

After the repository reference resolves, the provider determines whether to fetch binary content. At lines 42-50, the code checks if (settings.lfs && !settings.sparseCheckout). When both conditions are met, it executes await git.lfsFetch(checkoutInfo.startPoint || checkoutInfo.ref), which downloads the actual large files referenced by the LFS pointers. This fetch occurs as a batch operation rather than per-file, significantly improving performance over lazy smudging.

Sparse Checkout Interactions

When sparse checkout is enabled alongside LFS, the action deliberately skips the explicit git lfs fetch call. In this scenario, LFS objects fetch lazily during the checkout step itself, downloading only the binary files that match the sparse checkout paths. This prevents unnecessary bandwidth usage for large files excluded from the partial checkout scope.

Workflow Configuration Examples

Configure LFS handling in your workflow using the lfs input parameter.

Default behavior excludes LFS objects:

steps:
  - uses: actions/checkout@v4
    # LFS defaults to false; pointer files download without binary content

Enable full LFS support for repositories with binary assets:

steps:
  - uses: actions/checkout@v4
    with:
      lfs: true
      # Installs git-lfs and fetches all binary objects

Combine LFS with sparse checkout for selective large file retrieval:

steps:
  - uses: actions/checkout@v4
    with:
      lfs: true
      sparse-checkout: |
        assets/images
      # LFS objects fetch on-demand for specified paths only

Summary

  • Input handling: The lfs boolean is parsed in src/input-helper.ts and defaults to false for backward compatibility.
  • Performance optimization: When disabled, GIT_LFS_SKIP_SMUDGE=1 is set in src/git-command-manager.ts to prevent automatic downloads.
  • Installation: Enabled LFS triggers git.lfsInstall() in src/git-source-provider.ts with version validation (≥2.1).
  • Fetching: Binary objects download via git.lfsFetch() unless sparse checkout is active, which defers fetching to the checkout phase.
  • Testing: The repository includes __test__/verify-lfs.sh for validating LFS behavior across different configuration scenarios.

Frequently Asked Questions

When should I enable LFS in actions/checkout?

Enable the lfs: true input when your repository contains Git LFS pointer files that workflow steps must access as actual binary content, such as compiled artifacts, media files, or large datasets. If your workflow only needs the pointer files (text references) or uses sparse checkout to limit file scope, keeping the default false improves speed and reduces bandwidth consumption.

Does enabling LFS slow down the checkout process?

Enabling LFS adds two network operations: installing the git-lfs binary and fetching binary objects via git lfs fetch. While this increases checkout time compared to pointer-only downloads, the implementation in src/git-source-provider.ts optimizes performance by batch-fetching objects rather than downloading them individually during checkout. The GIT_LFS_SKIP_SMUDGE=1 optimization when disabled ensures you only pay the performance cost when explicitly requested.

How does actions/checkout handle LFS with sparse checkout?

When both lfs: true and sparse-checkout are specified, the action skips the explicit git lfs fetch step in src/git-source-provider.ts. Instead, LFS objects download lazily as the sparse checkout extracts files from the index. This prevents fetching large files that reside outside the sparse checkout cone, optimizing both storage and network usage for monorepos containing substantial binary assets.

What Git LFS version does actions/checkout require?

According to the validation logic in src/git-command-manager.ts, actions/checkout requires Git LFS version 2.1 or higher. The command manager checks the installed version during initialization and fails fast if the runner's environment contains an outdated binary, ensuring reliable operation of LFS commands used during the fetch phase.

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 →