# How Git LFS Integration Works in actions/checkout: A Technical Deep Dive

> Explore how Git LFS integration works in actions/checkout. Learn about its three-phase pipeline that installs LFS, fetches large files, and defers object retrieval for efficient workflows.

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

---

**Git LFS integration in actions/checkout operates through a coordinated three-phase pipeline that installs the LFS extension locally, fetches large files after the standard Git fetch completes, and defers object retrieval when sparse checkout is configured to minimize unnecessary network traffic.**

The `actions/checkout` action provides native support for Git Large File Storage (LFS) through an opt-in workflow input that triggers automatic handling of binary assets and large files. When enabled, the action seamlessly integrates LFS operations into the standard checkout flow without requiring manual Git commands. Understanding this Git LFS integration in actions/checkout helps you optimize CI/CD pipelines that handle media files, datasets, or other large binary dependencies.

## Enabling LFS via the Workflow Input

LFS support is controlled by the `lfs` input parameter, which defaults to `false` in the action configuration. When you set `lfs: true` in your workflow, this value propagates into the `IGitSourceSettings` interface, specifically the `lfs` boolean property defined in [`src/git-source-settings.ts`](https://github.com/actions/checkout/blob/main/src/git-source-settings.ts) at line 63. This flag serves as the gatekeeper for all downstream LFS operations.

```yaml
- name: Checkout with LFS
  uses: actions/checkout@v7
  with:
    lfs: true
    fetch-depth: 0

```

According to the source code in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts), the action checks this flag before executing any LFS-related commands, ensuring that standard checkouts remain lightweight when LFS is not required.

## Phase 1: Installing the LFS Extension

When `settings.lfs` evaluates to true, the action immediately runs `git lfs install --local` to prepare the repository. This occurs in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) between lines 69-73, where the code calls `git.lfsInstall()`.

This installation step configures the local repository to use the LFS filter, setting up the necessary Git hooks and filters without modifying the global Git configuration. The command executes before any fetch operations begin, ensuring that LFS is fully initialized when the actual file content is retrieved.

## Phase 2: Fetching LFS Objects

After the standard `git fetch` resolves the commit or tag reference, the action explicitly retrieves LFS objects through `git lfs fetch origin <ref>`. This logic resides in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) at lines 42-48, implemented via the `git.lfsFetch(...)` method.

Unlike standard Git objects, LFS pointers are replaced with actual file content during this phase. The fetch operation.targeted to the specific reference checked out, avoiding unnecessary downloads of LFS objects from other branches or historical commits not included in the current checkout scope.

## Sparse Checkout Interactions

When a **sparse checkout** is configured, the LFS fetching behavior changes significantly. Rather than immediately fetching all LFS objects, the action defers retrieval to support lazy loading. This optimization prevents downloading large files that fall outside the sparse checkout paths, reducing network usage and checkout time for workflows that only need specific subdirectories of a repository.

The conditional logic in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) checks for sparse checkout configurations before invoking `git.lfsFetch()`, ensuring that large files are only retrieved when their containing paths are actually checked out.

## Command-Level Implementation Details

Both LFS commands are implemented as thin wrappers around the Git CLI in [`src/git-command-manager.ts`](https://github.com/actions/checkout/blob/main/src/git-command-manager.ts). The `lfsInstall()` method appears at lines 95-97, while `lfsFetch()` is defined at lines 86-92. These methods use the internal `GitCommandManager` class, which provides:

- **Unified retry logic**: Both commands execute through `retryHelper.execute`, giving them the same resilience as standard Git operations against transient network failures
- **Consistent authentication**: LFS operations inherit the same credential helpers and authentication tokens configured for the main repository fetch
- **Error propagation**: Failures in LFS commands surface as workflow errors with appropriate exit codes

This architecture ensures that LFS operations are as reliable as standard Git commands within the action environment.

## Complete Workflow Example

Here is a practical workflow configuration that demonstrates Git LFS integration:

```yaml

# .github/workflows/lfs-workflow.yml

name: Build with Large Assets
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository with LFS
        uses: actions/checkout@v7
        with:
          lfs: true
          fetch-depth: 0
      
      - name: Verify LFS files
        run: |
          git lfs ls-files
          # Continue with build steps that require large files...

```

The action validates LFS functionality through the [`__test__/verify-lfs.sh`](https://github.com/actions/checkout/blob/main/__test__/verify-lfs.sh) script included in the repository's test suite, ensuring that the integration works correctly across different runner environments.

## Summary

- **Opt-in activation**: Set the `lfs` input to `true` to enable the integration, which stores the flag in `IGitSourceSettings.lfs` at [`src/git-source-settings.ts`](https://github.com/actions/checkout/blob/main/src/git-source-settings.ts) line 63.
- **Two-stage initialization**: The action runs `git lfs install --local` (lines 69-73 in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts)) before fetching, then executes `git lfs fetch origin <ref>` (lines 42-48) after the standard Git fetch.
- **Sparse checkout optimization**: LFS object fetching is deferred when sparse checkout is active, preventing unnecessary downloads of files outside the checkout scope.
- **Resilient execution**: Both LFS commands leverage the `retryHelper.execute` mechanism in [`src/git-command-manager.ts`](https://github.com/actions/checkout/blob/main/src/git-command-manager.ts) for automatic retry on transient failures.

## Frequently Asked Questions

### How do I enable Git LFS in my actions/checkout workflow?

Add `lfs: true` to the `with` block of your checkout step. This boolean input defaults to `false` and is documented in the [`README.md`](https://github.com/actions/checkout/blob/main/README.md) at lines 148-151. Once enabled, the action automatically handles LFS installation and fetching without requiring additional steps in your workflow.

### Does actions/checkout fetch LFS files during sparse checkout?

No, when sparse checkout is configured, the action defers LFS fetching to avoid downloading large files that are not included in the sparse checkout paths. This lazy loading approach minimizes network traffic and storage usage for workflows that only need specific portions of a repository.

### What happens if the LFS fetch fails due to network issues?

The LFS commands inherit the same retry logic as standard Git operations through the `retryHelper.execute` wrapper in [`src/git-command-manager.ts`](https://github.com/actions/checkout/blob/main/src/git-command-manager.ts). Transient network failures trigger automatic retries with exponential backoff, and persistent failures will fail the checkout step with appropriate error messages propagated to the workflow logs.

### Where is the LFS fetched data stored during the checkout?

LFS objects are stored in the local Git LFS cache within the checked-out repository, typically under `.git/lfs/objects/`. The `git lfs fetch` command executed by the action (lines 86-92 in [`src/git-command-manager.ts`](https://github.com/actions/checkout/blob/main/src/git-command-manager.ts)) downloads these objects to the local cache, and the subsequent checkout process replaces LFS pointer files with the actual content from this cache.