Skip to content
Latchkey

git fetch --deepen and --unshallow in CI

git fetch --deepen=<n> extends a shallow clone by n more commits, and git fetch --unshallow downloads the full remaining history.

CI defaults like actions/checkout fetch-depth: 1 break any step that needs older commits: diffs, blame, describe, merge-base. --deepen and --unshallow are the targeted fixes that avoid re-cloning.

What it does

A shallow clone has a truncated history. git fetch --deepen=<n> adds n commits of history below the current shallow boundary. git fetch --unshallow fetches everything left, converting it to a full clone. --depth=<n> (on fetch) sets the absolute depth rather than adding to it.

Common usage

Terminal
# add 50 more commits of history
git fetch --deepen=50
# fetch all remaining history
git fetch --unshallow
# fetch tags too (needed for git describe)
git fetch --tags --unshallow
# deepen just one branch
git fetch --deepen=100 origin main

Options

FlagWhat it does
--deepen=<n>Add n commits below the shallow boundary
--depth=<n>Set absolute depth (may add or truncate)
--unshallowFetch the complete remaining history
--shallow-since=<date>Deepen to a date instead of a count
--tagsAlso fetch tags (often needed after deepening)

In CI

With actions/checkout, set fetch-depth: 0 for a full history or a number for partial, instead of deepening afterward. If you must deepen in-job, run git fetch --unshallow --tags before any git describe step, since shallow clones usually omit tags. --unshallow errors on a clone that is already complete.

Common errors in CI

"fatal: --unshallow on a complete repository does not make sense" means the clone is not shallow; guard with git rev-parse --is-shallow-repository. "fatal: error in object: unshallow <sha>" can appear with corrupt shallow boundaries; re-clone. A later "fatal: No names found, cannot describe anything" usually means tags were not fetched, not a depth issue.

Using this in CI

CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.

.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # history, tags, and git describe all need this

- run: |
    git rev-parse --is-shallow-repository   # expect false
    git rev-parse --abbrev-ref HEAD          # prints HEAD when detached

Frequently asked questions

git fetch --deepen and --unshallow in CI?
CI defaults like actions/checkout fetch-depth: 1 break any step that needs older commits: diffs, blame, describe, merge-base. --deepen and --unshallow are the targeted fixes that avoid re-cloning.
What it does?
A shallow clone has a truncated history. git fetch --deepen=<n> adds n commits of history below the current shallow boundary. git fetch --unshallow fetches everything left, converting it to a full clone. --depth=<n> (on fetch) sets the absolute depth rather than adding to it.
In CI?
With actions/checkout, set fetch-depth: 0 for a full history or a number for partial, instead of deepening afterward. If you must deepen in-job, run git fetch --unshallow --tags before any git describe step, since shallow clones usually omit tags. --unshallow errors on a clone that is already complete.
Common errors in CI?
"fatal: --unshallow on a complete repository does not make sense" means the clone is not shallow; guard with git rev-parse --is-shallow-repository. "fatal: error in object: unshallow <sha>" can appear with corrupt shallow boundaries; re-clone.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card