# How to Fetch the Full Git History with actions/checkout: A Complete Guide

> Learn how actions/checkout fetches full Git history. Set fetch-depth 0 in your workflow for complete commit history, branches, and tags, avoiding shallow clones.

- Repository: [GitHub Actions/checkout](https://github.com/actions/checkout)
- Tags: how-to-guide
- Published: 2026-07-05

---

**Set `fetch-depth: 0` in your workflow configuration to retrieve the complete commit history, including all branches and tags, instead of the default shallow clone.**

The `actions/checkout` repository provides the official GitHub Action for checking out repositories in CI workflows. By default, it performs a shallow fetch with `fetch-depth: 1` to optimize performance, but many workflows require access to the entire git history for operations like versioning, changelog generation, or blame analysis.

## How Full History Fetching Works in actions/checkout

The action determines how much history to download based on the numeric `fetch-depth` input. When this value is `0` or negative, the action bypasses shallow clone optimizations and fetches all refs from the remote repository.

### Input Parsing in [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts)

In [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts), the action reads the `fetch-depth` input and converts it to a number, defaulting to `1` if not specified:

```typescript
// src/input-helper.ts
result.fetchDepth = Math.floor(Number(core.getInput('fetch-depth') || '1'))
if (isNaN(result.fetchDepth) || result.fetchDepth < 0) {
  result.fetchDepth = 0               // treat negative/NaN as "full history"
}

```

*Source:* [src/input-helper.ts](https://github.com/actions/checkout/blob/main/src/input-helper.ts)

### Fetch Logic in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts)

The checkout logic in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) branches based on the `fetchDepth` value. When `fetchDepth <= 0`, it invokes the full history fetch path:

```typescript
// src/git-source-provider.ts
if (settings.fetchDepth <= 0) {
  // fetch **all** branches and tags
  let refSpec = refHelper.getRefSpecForAllHistory(settings.ref, settings.commit)
  await git.fetch(refSpec, fetchOptions)
  …
} else {
  // shallow fetch according to the specified depth
  fetchOptions.fetchDepth = settings.fetchDepth
  const refSpec = refHelper.getRefSpec(settings.ref, settings.commit, settings.fetchTags)
  await git.fetch(refSpec, fetchOptions)
}

```

*Source:* [src/git-source-provider.ts](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts)

### Ref Specification in [`src/ref-helper.ts`](https://github.com/actions/checkout/blob/main/src/ref-helper.ts)

When fetching full history, the `refHelper.getRefSpecForAllHistory` function generates ref specs that include all branch heads and tags:

```typescript
// src/ref-helper.ts
export function getRefSpecForAllHistory(ref: string, commit: string): string[] {
  const result = ['+refs/heads/*:refs/remotes/origin/*', tagsRefSpec]
  …
  return result
}

```

This creates fetch refs for `+refs/heads/*:refs/remotes/origin/*` plus all tags.

## Workflow Configuration Examples

### Basic Full History Checkout

To fetch the complete commit history, set `fetch-depth: 0`:

```yaml
name: CI-full-history
on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout full repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - run: git log --oneline --graph --decorate --all | head -20

```

### Fetching Tags with Full History

When you need both full history and all tags:

```yaml
steps:
  - uses: actions/checkout@v4
    with:
      fetch-depth: 0      # full history

      fetch-tags: true    # ensure tags are downloaded as well

```

### Matrix Strategy for Testing Different Depths

You can test different fetch depths using a matrix strategy:

```yaml
strategy:
  matrix:
    depth: [1, 10, 0]   # shallow, medium, full

steps:
  - uses: actions/checkout@v4
    with:
      fetch-depth: ${{ matrix.depth }}

```

## Key Implementation Files

The full-history checkout behavior is implemented across several key files in the `actions/checkout` repository:

- **[`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts)**: Parses and normalizes the `fetch-depth` input value, converting negative numbers or NaN to `0` to indicate full history.
- **[`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts)**: Contains the main logic that decides between shallow fetching and full history fetching based on the `fetchDepth` setting.
- **[`src/ref-helper.ts`](https://github.com/actions/checkout/blob/main/src/ref-helper.ts)**: Generates the appropriate git ref specifications, including `+refs/heads/*:refs/remotes/origin/*` for all branches when full history is requested.
- **[`action.yml`](https://github.com/actions/checkout/blob/main/action.yml)**: Defines the `fetch-depth` input with its default value of `1` and documents the behavior when set to `0`.

## Summary

- Set **`fetch-depth: 0`** in your workflow to fetch the complete git history with `actions/checkout`.
- The default `fetch-depth` is `1`, creating a shallow clone for performance.
- When `fetch-depth` is `0` or negative, the action fetches all branches and tags using ref specs generated by `refHelper.getRefSpecForAllHistory`.
- Use **`fetch-tags: true`** alongside `fetch-depth: 0` to ensure all tags are retrieved.
- The implementation is located in [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts), [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts), and [`src/ref-helper.ts`](https://github.com/actions/checkout/blob/main/src/ref-helper.ts).

## Frequently Asked Questions

### What is the default fetch depth in actions/checkout?

By default, `actions/checkout` uses a `fetch-depth` of `1`, which performs a shallow clone containing only the most recent commit. This optimization reduces checkout time and storage usage for workflows that do not require historical commit data.

### Can I use a negative number instead of zero for fetch-depth?

Yes, according to the source code in [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts), any negative value or NaN is normalized to `0`, which triggers the full history fetch behavior. However, using `fetch-depth: 0` is the recommended explicit syntax for clarity and maintainability.

### Does fetch-depth: 0 include all tags?

Setting `fetch-depth: 0` includes the ref specs for tags in the fetch command via `refHelper.getRefSpecForAllHistory`, but you should also set `fetch-tags: true` to ensure tags are explicitly fetched, especially in older versions or specific ref configurations.

### How do I fetch only specific tags with full history?

To fetch full history while controlling tag fetching, use `fetch-depth: 0` with `fetch-tags: false` (or omit `fetch-tags`), then run a separate `git fetch origin tag/<tag-name>` command for specific tags in a subsequent step.