This content originally appeared on DEV Community and was authored by Cristian Sifuentes
git clone Like a Pro: From -b develop to Partial & Sparse Clones (Basic → Expert)
You don’t just clone a repo—you curate what you bring home: branches, history depth, files, and even large assets. Here’s your tiered playbook.
BASIC — “Just grab what I need”
Clone default branch
git clone https://github.com/owner/repo.git
By default Git creates remote-tracking branches for all remote branches and checks out an initial branch matching the remote’s active branch.
Clone and check out a specific branch (e.g., develop
)
git clone -b develop https://github.com/owner/repo.git
# Tip: Add --single-branch to fetch only that branch’s history
git clone -b develop --single-branch https://github.com/owner/repo.git
--single-branch
limits the clone to the chosen branch’s history (or the remote’s HEAD if -b
is omitted).
Fast start (shallow)
git clone --depth 1 -b develop --single-branch https://github.com/owner/repo.git
--depth N
fetches only the most recent N commits; shallow clones also only fetch history for the branch you ask for.
MEDIUM — “Make it tidy & predictable”
Choose HTTPS vs SSH
# HTTPS (easy to start)
git clone https://github.com/owner/repo.git
# SSH (great for contributors)
git clone [email protected]:owner/repo.git
Name the remote differently or set configs at clone time
git clone -o upstream https://github.com/owner/repo.git
git clone -c core.autocrlf=input https://github.com/owner/repo.git
Use -o
to rename origin
, and -c key=value
to seed config on the new repo.
Skip tags (lighter fetch)
git clone --no-tags --single-branch -b develop https://github.com/owner/repo.git
--no-tags
avoids fetching tag refs on clone. You can fetch tags later with git fetch --tags
.
GitHub CLI pass-through
gh repo clone owner/repo -- -b develop --depth 1 --single-branch
Everything after --
is forwarded to git clone
.
ADVANCED — “Big repos, small footprint”
Partial clone (blobless)
git clone --filter=blob:none https://github.com/owner/repo.git
# Combine for speed:
git clone --filter=blob:none --depth 1 -b develop --single-branch https://github.com/owner/repo.git
Partial clone avoids downloading file contents (blobs) up front; blobs are fetched on demand during checkout. Great for huge codebases.
Sparse checkout (mono-repo surgery)
git clone --filter=blob:none https://github.com/owner/repo.git
cd repo
git sparse-checkout init --cone
git sparse-checkout set apps/web libs/ui
Sparse checkout materializes only selected directories in your working tree—perfect for mono-repos and CI.
Submodules, the right way
git clone --recurse-submodules https://github.com/owner/repo.git
# (Optional) keep submodules shallow too:
git clone --recurse-submodules --shallow-submodules https://github.com/owner/repo.git
--recurse-submodules
initializes & updates submodules during clone; --shallow-submodules
keeps them light.
Git LFS: skip heavy assets at clone time
# one-off
GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/owner/huge-lfs-repo.git
# or set globally
git lfs install --skip-smudge
Skips automatic LFS download during clone; fetch assets later when needed with git lfs pull
.
EXPERT — “Admin, mirrors, provenance & power moves”
Mirror vs bare (for backups & CI mirrors)
# Exact mirror of all refs (includes notes, refs, etc.)
git clone --mirror https://github.com/owner/repo.git /backups/repo.git
# A bare working repo (no working tree)
git clone --bare https://github.com/owner/repo.git
--mirror
implies --bare
and tracks all refs for 1:1 replication. Use git remote update
to refresh.
Separate .git
directory (ephemeral working trees)
git clone --separate-git-dir=/var/git/repo.git https://github.com/owner/repo.git worktree
Keeps the object database outside your working directory—handy for build agents and scratch trees.
Reproducible, minimal checkouts (combine techniques)
git clone --filter=blob:none --single-branch -b release/2025.09 --depth 20 --no-tags https://github.com/owner/big-mono.git
cd big-mono
git sparse-checkout init --cone
git sparse-checkout set services/api
You now have a tiny, fast, branch-specific, directory-focused working copy.
Cheat-Sheet: Pick your recipe
Goal | Command |
---|---|
Specific branch only | git clone -b <name> --single-branch <url> |
Latest commit only | git clone --depth 1 <url> |
Blobless & shallow | git clone --filter=blob:none --depth 1 <url> |
Sparse paths | git sparse-checkout init --cone && git sparse-checkout set <dirs> |
With submodules | git clone --recurse-submodules <url> |
Skip LFS at clone | GIT_LFS_SKIP_SMUDGE=1 git clone <url> |
Exact mirror | git clone --mirror <url> |
GitHub CLI + flags | gh repo clone owner/repo -- -b develop --depth 1 |
Common pitfalls (and quick fixes)
-
Cloned with
-b develop
but fetch pulled all branches? Add--single-branch
to limit history to that branch on the initial clone. -
Shallow clone breaks tools like
git describe
or deep merges? Deepen when needed:git fetch --deepen 200
or unshallow with a full fetch:git fetch --unshallow
. -
Partial clone feels “missing files”? That’s expected; blobs download on demand at checkout. Consider
--filter=blob:limit=<bytes>
when some large blobs are needed. -
Sparse checkout not reducing clone time? Sparse limits the working tree; combine with
--filter=blob:none
and/or shallow depth to shrink transfer. -
Submodules out of sync? Use
--recurse-submodules
at clone, or rungit submodule update --init --recursive
.
Mental model: Why so many knobs?
Think of git clone
as a pipeline:
1) Discover refs (branches/tags) →
2) Decide history (--single-branch
, --depth
) →
3) Decide objects (--filter
partial clone) →
4) Decide files on disk (sparse checkout) →
5) Extras (submodules, LFS, mirror/bare, configs).
Dial each stage only as much as your use‑case needs.
Final Thoughts
- For everyday work on one branch:
-b <name> --single-branch --depth 1
is a great default. - For massive repos: add
--filter=blob:none
and sparse-checkout your sub-tree. - For CI mirrors/backups:
--mirror
is your friend. - For GitHub CLI users: remember the
--
pass‑through.
Clone less. Build more.
This content originally appeared on DEV Community and was authored by Cristian Sifuentes