How to Perform the Actual Git Checkout in actions/checkout

The actual Git checkout in actions/checkout is executed by the git.checkout() method in src/git-source-provider.ts (lines 69-73), which invokes the native Git command through an IGitCommandManager instance after resolving the target ref via refHelper.getCheckoutInfo.

The actions/checkout repository is the official GitHub Action for checking out source code in CI/CD workflows. Understanding how it performs the actual Git checkout requires examining the TypeScript implementation that orchestrates the process from workflow inputs to the final git checkout command execution.

The Checkout Execution Flow

The checkout process follows a precise sequence implemented across several TypeScript modules in the repository.

Input Parsing and Repository Resolution

According to the source code, the process begins with inputHelper.getInputs() in src/input-helper.ts, which reads the with: values from the workflow YAML (e.g., ref, fetch-depth, sparse-checkout). The action then uses urlHelper.getFetchUrl to build the HTTPS or SSH URL for fetching the repository.

Directory Preparation and Authentication

Before executing the checkout, the action prepares the target directory. If the path already contains a Git repository, the action either cleans it using git clean && git reset or removes the directory entirely. The gitAuthHelper module writes temporary credentials (PAT or SSH key) into the local Git config, and getGitCommandManager ensures a compatible Git binary is available; otherwise, the action falls back to the REST API download.

The Final Git Checkout Command

The actual checkout occurs at lines 69-73 of src/git-source-provider.ts:

await git.checkout(checkoutInfo.ref, checkoutInfo.startPoint)

Here, git is an instance of IGitCommandManager, created earlier by gitCommandManager.createCommandManager in src/git-command-manager.ts. This manager wraps native Git commands and adds safety handling such as automatic garbage-collection disabling and sparse-checkout support.

The checkout information (checkoutInfo.ref and checkoutInfo.startPoint) is assembled by refHelper.getCheckoutInfo in src/ref-helper.ts. It determines exactly which commit or tag should be checked out based on the inputs ref, commit, and any fetch-depth settings.

If sparse-checkout is enabled, the action configures Git's sparse-checkout mode before the final checkout, materializing only the specified paths.

Configuring Checkout Behavior in Workflows

You can control how the checkout executes using various workflow inputs.

Basic Checkout (Default Behavior)

- uses: actions/checkout@v7

This checks out the repository that triggered the workflow at the commit identified by $GITHUB_SHA.

Checkout a Specific Branch or Tag

- uses: actions/checkout@v7
  with:
    ref: "release-v1.2.3"

The action fetches the release-v1.2.3 ref and runs git checkout release-v1.2.3.

Full History (All Branches and Tags)

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

Setting fetch-depth: 0 disables shallow clone, using git fetch --depth=0 to retrieve the complete repository history before checkout.

Sparse Checkout (Only Selected Paths)

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

This enables Git's sparse-checkout mode, then git checkout only materializes the listed paths.

Using an SSH Key for Private Repositories

- uses: actions/checkout@v7
  with:
    ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
    persist-credentials: false

The action writes the SSH key to a temporary config, performs the fetch, and removes the key during cleanup.

Key Source Files and Implementation Details

The checkout lifecycle is implemented across these critical files:

  • src/main.ts: Entry point that decides between the pre-step (run) and post-step (cleanup). The cleanup function at lines 40-47 removes temporary credentials after the job finishes.

  • src/git-source-provider.ts: Orchestrates repository preparation, fetching, and the final git checkout at lines 69-73.

  • src/git-command-manager.ts: Wraps low-level Git commands (init, fetch, checkout, lfs*, etc.) and creates the IGitCommandManager instance.

  • src/ref-helper.ts: Determines the ref-specs and checkout targets based on inputs via getCheckoutInfo.

  • src/input-helper.ts: Parses workflow inputs into an IGitSourceSettings object.

All steps are wrapped in a try … finally block that triggers cleanup via stateHelper.IsPost to ensure credentials are removed after execution.

Summary

  • The actual Git checkout executes in src/git-source-provider.ts via git.checkout(checkoutInfo.ref, checkoutInfo.startPoint) at lines 69-73.
  • The IGitCommandManager interface wraps native Git commands and is created by gitCommandManager.createCommandManager.
  • Checkout targets are resolved by refHelper.getCheckoutInfo in src/ref-helper.ts based on workflow inputs.
  • Authentication credentials are managed by gitAuthHelper and cleaned up in src/main.ts (lines 40-47) after the job completes.
  • The action supports advanced configurations including sparse checkout, shallow clones, and SSH authentication.

Frequently Asked Questions

How does actions/checkout determine which commit to check out?

The action uses refHelper.getCheckoutInfo in src/ref-helper.ts to resolve the target ref based on the ref input. If no ref is specified, it defaults to the commit identified by $GITHUB_SHA. The helper determines the appropriate start point and whether to create a detached HEAD or check out a specific branch.

What happens if the target directory already contains a Git repository?

If the target path already contains a Git repository, the action either cleans it using git clean && git reset or removes the directory entirely before proceeding. This ensures a clean state for the new checkout operation.

How does the action handle authentication credentials securely?

The gitAuthHelper module writes temporary credentials (PAT or SSH keys) into the local Git config before fetching and checking out. These credentials are automatically removed during the cleanup phase triggered by stateHelper.IsPost in src/main.ts (lines 40-47), which runs even if the job fails.

Can I check out only specific files or directories?

Yes, by using the sparse-checkout input. When enabled, the action configures Git's sparse-checkout mode before the final checkout in src/git-source-provider.ts, causing git checkout to only materialize the paths specified in the sparse-checkout list.

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 →