How to convert a Git shallow clone to a full clone?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
A shallow clone (git clone --depth 1) downloads only the latest commit (or a specified number of recent commits) without the full repository history. This speeds up cloning for large repositories but prevents operations that need history: git log, git blame, git bisect, and generating changelogs. Converting a shallow clone to a full clone retrieves the missing history from the remote.
The Quick Fix
This single command fetches all missing commits, tags, and branches from the remote, converting the shallow clone into a full clone with complete history.
Verify the conversion:
If the output is false, the repository now has full history.
What --unshallow Actually Does
A shallow clone stores a marker file at .git/shallow listing the commit SHAs where history was cut off. git fetch --unshallow does three things:
- Fetches all commits from the remote that are ancestors of the shallow boundary commits
- Fetches all commits on all remote branches (not just the checked-out branch)
- Removes the
.git/shallowfile
Fetching All Branches and Tags
--unshallow fetches history for the current branch's remote. To ensure you have everything:
--all fetches from all configured remotes (useful if you have multiple remotes like origin and upstream). --tags ensures annotated tags are downloaded.
Deepening Incrementally Instead of Full Fetch
If you do not need the entire history but want more than the shallow clone provided:
Incremental deepening is useful when the full history is enormous (hundreds of thousands of commits) and you only need history back to a certain point.
Handling CI/CD Shallow Clones
Most CI systems shallow-clone by default for speed. If your build step needs full history (for versioning, changelogs, or git describe), you need to either configure the CI to do a full clone or deepen after checkout.
GitHub Actions
GitLab CI
Jenkins
Bitbucket Pipelines
When the Remote Does Not Support --unshallow
Some Git hosting configurations or older Git versions may not support --unshallow. The fallback is to fetch with a very large depth:
This requests effectively unlimited history, achieving the same result as --unshallow.
If even that fails, re-clone from scratch:
Checking If a Repository Is Shallow
Shallow Clone vs Partial Clone
Git 2.22+ introduced partial clones, which are different from shallow clones:
Partial clones keep full commit history but skip file contents until needed. This gives you git log, git blame, and git bisect without downloading large binary files upfront. For most CI and development use cases, partial clones are a better choice than shallow clones.
Common Pitfalls
git logshows only recent commits: This is the most visible symptom of a shallow clone. Rungit fetch --unshallowto get full history.git pushfails from a shallow clone: Pushing from a shallow clone can fail if the remote requires history that the local clone does not have. Unshallow before pushing.git submodulewith shallow clones: Submodules can be independently shallow. Usegit submodule update --init --recursive --depth=0(Git 2.10+) or--no-shallow-submodulesto ensure submodules get full history.- Disk space after unshallowing: A full clone of a large repository can be significantly larger. For the Linux kernel, a shallow clone is about 200 MB while a full clone is over 4 GB.
- Network bandwidth:
--unshallowdownloads the entire missing history in one fetch. On slow connections, consider--deepenincrementally or use--shallow-sinceto limit how far back you go.
Summary
- Run
git fetch --unshallowto convert a shallow clone to a full clone - Verify with
git rev-parse --is-shallow-repository(should returnfalse) - Use
git fetch --all --tagsto ensure all branches and tags are downloaded - Configure CI systems with
fetch-depth: 0to avoid shallow clones when full history is needed - Use
--deepenor--shallow-sincefor partial history expansion without downloading everything - Consider partial clones (
--filter=blob:none) as a modern alternative to shallow clones
Related reading
- How to convert a normal Git repository to a bare one?
- How to convert existing non-empty directory into a Git working directory and push files to a remote repository
- How to convert existing non-empty directory into a Git working directory and push files to a remote repository
- How to copy commits from one branch to another?
- How to copy commits from one branch to another?
- How to copy Docker images from one host to another without using a repository
- How to count total lines changed by a specific author in a Git repository?
- How to create a git patch from the uncommitted changes in the current working directory without creating a commit?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.