Fast full-history checkouts
actions/checkout fetches one commit by default (fetch-depth: 1). That is the fastest checkout, and the right one for most jobs.
Some jobs need history: comparing a pull request against its base branch, finding the last release tag, or generating a changelog. Those set fetch-depth: 0, which downloads every version of every file the repository has ever had. Most of those jobs only read commits and file names, never the old file contents.
Add one line
- uses: actions/checkout@v4
with:
fetch-depth: 0
filter: blob:nonefilter: blob:none makes a partial clone: all commits and directory listings, and file contents only for the commit you check out. If a later step reads an older version of a file, git downloads it at that moment.
What it saves
Measured on fremforge’s own largest repository (about 5,000 files, 4,600 commits), on hosted runners, October 2026:
| Checkout | Fetch | Check out files | Total |
|---|---|---|---|
fetch-depth: 0 | 23.4 s | 0.5 s | about 24 s |
fetch-depth: 0 + filter: blob:none | 3.4 to 3.9 s | 6.4 to 6.5 s | about 10 s |
The saving grows with the repository’s history. A young repository with few commits gains little.
When to use it
Use it when the job’s git commands read commits, branches, tags or names of changed files, for example:
git diff --name-only origin/main...HEADgit log --oneline,git describe --tagsgit merge-base
Leave it off when the job reads old file contents across many commits, for example git log -p over a long range, git blame on many files, or a tool that walks every historical version. Each missing file is then downloaded on demand, which can be slower than the full clone.
A git diff that shows content (not just names) between two commits downloads only the files that changed, in one batch. That is usually still faster than a full clone.
Why this is not the default
fremforge does not turn this on for every job, for two reasons:
- It slows the default checkout. With
fetch-depth: 1, a partial clone needs a second round trip for the files, so it is slower, not faster. - The repository needs its own settings to work. The
filterinput writes the partial-clone settings into the checked-out repository, so any later step can fetch what it needs. A setting applied to the runner as a whole would not travel with the repository, and a step running with a different home directory, for example inside a job container, would fail on the first missing file.
So the choice stays with you, per workflow.