How to Fetch the Full Git History with actions/checkout: A Complete Guide
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
In src/input-helper.ts, the action reads the fetch-depth input and converts it to a number, defaulting to 1 if not specified:
// 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
Fetch Logic in src/git-source-provider.ts
The checkout logic in src/git-source-provider.ts branches based on the fetchDepth value. When fetchDepth <= 0, it invokes the full history fetch path:
// 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
Ref Specification in src/ref-helper.ts
When fetching full history, the refHelper.getRefSpecForAllHistory function generates ref specs that include all branch heads and tags:
// 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:
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:
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:
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: Parses and normalizes thefetch-depthinput value, converting negative numbers or NaN to0to indicate full history.src/git-source-provider.ts: Contains the main logic that decides between shallow fetching and full history fetching based on thefetchDepthsetting.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: Defines thefetch-depthinput with its default value of1and documents the behavior when set to0.
Summary
- Set
fetch-depth: 0in your workflow to fetch the complete git history withactions/checkout. - The default
fetch-depthis1, creating a shallow clone for performance. - When
fetch-depthis0or negative, the action fetches all branches and tags using ref specs generated byrefHelper.getRefSpecForAllHistory. - Use
fetch-tags: truealongsidefetch-depth: 0to ensure all tags are retrieved. - The implementation is located in
src/input-helper.ts,src/git-source-provider.ts, andsrc/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, 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.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →