How to Use actions/checkout in GitHub Actions: Complete Implementation Guide

The actions/checkout action clones your repository into $GITHUB_WORKSPACE by parsing workflow inputs through src/input-helper.ts and executing Git commands via src/git-source-provider.ts, making your code available to subsequent steps.

The actions/checkout action is the standard mechanism for accessing repository code inside GitHub Actions workflows. Understanding how to use actions/checkout in GitHub Actions effectively requires knowledge of its input parameters, internal execution flow, and security safeguards as implemented in the actions/checkout repository.

How the Checkout Action Works

actions/checkout is a JavaScript-based action that orchestrates repository access through a specific execution pipeline. The runner reads action.yml to determine available inputs and entry points, then executes the workflow defined in src/main.ts.

The execution flow follows these stages:

  1. Input Parsing – The getInputs() function in src/input-helper.ts reads workflow parameters, applies defaults (such as clean: true and fetch-depth: 1), and constructs an IGitSourceSettings object.
  2. Safety Validation – src/unsafe-pr-checkout-helper.ts validates the allow-unsafe-pr-checkout flag against pull request origins to prevent fork-based attacks.
  3. Git Configuration – src/git-source-provider.ts initializes the repository, configures authentication tokens, and prepares the working directory under $GITHUB_WORKSPACE/<path>.
  4. Fetch and Checkout – Based on settings like fetch-depth, filter, and fetch-tags, the provider executes git fetch and checks out the requested ref.
  5. Credential Cleanup – Unless persist-credentials: false is set, the action removes temporary tokens from Git config during the post-step cleanup.

Basic Usage Examples

Minimal Checkout

The simplest usage checks out the current repository at the default branch:

- uses: actions/checkout@v4

Checkout Specific Branches or Tags

Use the ref input to checkout a specific branch, tag, or commit SHA:

- uses: actions/checkout@v4
  with:
    ref: my-branch

Fetch Full History

By default, the action performs a shallow fetch (depth 1). Set fetch-depth: 0 to retrieve complete history for commands like git log or git describe:

- uses: actions/checkout@v4
  with:
    fetch-depth: 0

Advanced Configuration

Sparse Checkout

Limit downloaded data by configuring sparse checkout patterns in src/git-source-provider.ts before the fetch:

- uses: actions/checkout@v4
  with:
    sparse-checkout: |
      README.md
      src/
    sparse-checkout-cone-mode: false

Large File Storage (LFS)

Enable Git LFS to handle large files:

- uses: actions/checkout@v4
  with:
    lfs: true

Submodule Handling

Checkout nested submodules recursively:

- uses: actions/checkout@v4
  with:
    submodules: recursive

Cross-Repository Access

Access private repositories using a Personal Access Token (PAT) stored in secrets:

- uses: actions/checkout@v4
  with:
    repository: my-org/private-repo
    token: ${{ secrets.PAT }}

Security Considerations

The action includes security protections implemented in src/unsafe-pr-checkout-helper.ts. By default, it refuses to checkout code from forked pull requests unless explicitly authorized.

To checkout the PR head SHA instead of the merge commit:

- uses: actions/checkout@v4
  with:
    ref: ${{ github.event.pull_request.head.sha }}

To opt-in to potentially unsafe checkouts (only after reviewing security implications):

- uses: actions/checkout@v4
  with:
    allow-unsafe-pr-checkout: true

Summary

  • actions/checkout clones repositories into $GITHUB_WORKSPACE using a TypeScript-based implementation split across specialized source files.
  • Input processing occurs in src/input-helper.ts, which validates parameters and applies defaults before passing settings to the Git provider.
  • Security protections in src/unsafe-pr-checkout-helper.ts prevent accidental execution of untrusted fork code without explicit opt-in.
  • Advanced features include sparse checkout, LFS support, submodule handling, and cross-repository access via PAT authentication.

Frequently Asked Questions

How do I checkout a pull request branch instead of the merge commit?

Set the ref input to ${{ github.event.pull_request.head.sha }} to checkout the actual PR head rather than the merge commit. This configuration is useful when you need the exact commit state without GitHub's automatic merge into the base branch.

Why does my workflow fail when accessing private repositories?

Private repository access requires authentication via the token input. Configure a Personal Access Token with repo scope stored in repository secrets, then pass it to the action using token: ${{ secrets.PAT }}. The default GITHUB_TOKEN only has access to the current repository.

When should I use fetch-depth: 0 versus the default shallow checkout?

Use fetch-depth: 0 when your workflow requires complete Git history, such as for semantic versioning tools, git describe, or changelog generation. The default shallow checkout (depth 1) improves performance and reduces disk usage for builds that only need the latest commit.

What files control the actions/checkout behavior?

The action behavior is defined in action.yml (interface definition), src/main.ts (entry point), src/input-helper.ts (input validation), and src/git-source-provider.ts (Git command execution). Understanding these files helps debug complex checkout scenarios or contribute to the action.

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 →