git clone creates a full local copy of a remote repository — every branch, every tag, and the entire commit history, not just the current snapshot. This is the second post in this site’s Git command guide: once you’ve decided you’re not starting a project from scratch with git init, this is how you get an existing one onto your machine.
Basic Usage
$ git clone https://github.com/username/repo.git
Cloning into 'repo'...
remote: Enumerating objects: 142, done.
remote: Counting objects: 100% (142/142), done.
remote: Compressing objects: 100% (98/98), done.
remote: Total 142 (delta 31), reused 120 (delta 18), pack-reused 0
Receiving objects: 100% (142/142), 58.21 KiB | 2.91 MiB/s, done.
Resolving deltas: 100% (31/31), done.
This creates a new directory called repo in your current location, checks out the remote’s default branch, and sets up a remote named origin pointing back at the URL you cloned from.
Useful Flags: Shallow Clones, Specific Branches, Submodules
Cloning the entire history of a large, old repository can be slow and disk-hungry. If you just need to build or inspect the current state of the code, a shallow clone with --depth grabs only the most recent commits:
$ git clone --depth 1 https://github.com/username/repo.git
Cloning into 'repo'...
remote: Enumerating objects: 38, done.
remote: Total 38 (delta 0), reused 0 (delta 0), pack-reused 38
Receiving objects: 100% (38/38), 12.04 KiB | 12.04 MiB/s, done.
--depth 1 grabs only the latest commit on the default branch. This is what CI pipelines use — you rarely need full blame history just to run a build. Note that a shallow clone makes some operations (like older git log ranges, or pushing back upstream history) unavailable until you git fetch --unshallow.
To clone a specific branch instead of the default one:
$ git clone --branch develop --single-branch https://github.com/username/repo.git
--branch (or -b) checks out that branch immediately; adding --single-branch means Git won’t even fetch the refs for other branches, which combines well with --depth for a minimal clone.
If the repository uses submodules — nested repositories referenced from the parent, common in larger Java/Spring monorepos that pull in shared libraries — a plain clone leaves the submodule directories empty. Pull them in with:
$ git clone --recurse-submodules https://github.com/username/repo.git
If you forgot the flag and already have a clone, you don’t need to re-clone — run git submodule update --init --recursive inside the existing repo instead.
SSH vs HTTPS
You’ll see both URL forms in the wild — https://github.com/user/repo.git and [email protected]:user/repo.git. They clone the same content; the difference is entirely in authentication.
| HTTPS | SSH | |
|---|---|---|
| Setup | Works immediately; prompts for username/token on push | Requires generating a key pair and adding the public key to your GitHub/GitLab account first |
| Authentication | Personal access token (password auth was retired by GitHub in 2021) | SSH key pair, optionally protected by a passphrase |
| Repeated use | Needs a credential helper configured to avoid re-entering tokens | Just works once the key is registered, no per-push prompt |
| Firewalls | Uses port 443, rarely blocked | Uses port 22, sometimes blocked on corporate networks |
| Best for | Quick one-off clones, CI environments with token secrets | Daily development on machines you control |
A Real SSH Error: Permission Denied (publickey)
If you clone via SSH before your key is registered with the host, you’ll hit this:
$ git clone [email protected]:username/repo.git
Cloning into 'repo'...
[email protected]: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
This means the SSH server rejected every key it has on file for your connection — usually because you don’t have a key generated yet, or you do but it’s never been added to your GitHub account. Fix it by generating a key and registering the public half:
$ ssh-keygen -t ed25519 -C "[email protected]"
$ cat ~/.ssh/id_ed25519.pub
# copy the output and paste it into GitHub → Settings → SSH and GPG keys
$ ssh -T [email protected]
Hi username! You've successfully authenticated, but GitHub does not provide shell access.
That last ssh -T command is the one I actually use to verify the fix worked before retrying the clone — no point re-running a clone just to find out the key still isn’t recognized.
FAQs
Does git clone copy every branch?
Yes, by default it fetches all branches and tags, but only checks out the default branch into your working directory. Run git branch -a after cloning to see the rest, or git checkout <branch> to switch.
How do I clone into a specific folder name instead of the repo name?
Add a directory name as the second argument: git clone https://github.com/username/repo.git my-folder.
Can I switch a clone from HTTPS to SSH later without re-cloning?
Yes — update the remote URL: git remote set-url origin [email protected]:username/repo.git.
What does “shallow clone” actually limit?
It limits how much history you have locally, not which files exist. You get the complete, current working tree — just without the older commits behind it. Most builds and deploys don’t need that history at all.
See Also: This Site’s Git Command Guide
This post is part of a 13-part Git command guide on this site:
- Git Init — starting a brand-new repository
- Git Add — staging specific files for a commit
- Git Add . (All) — staging all changes at once
- Git Commit — saving staged changes to the repository
- Git Status — checking what’s changed before you commit
- Git Branch — creating, listing, and renaming branches
- Git Checkout — switching branches and restoring files
- Git Push — sending your commits to a remote
- Git Pull — fetching and merging remote changes
- Git Log — reading commit history
- Git: Delete Last Commit — undoing a commit safely
- Git – Autocorrect Spelling — typo recovery and productivity config
Conclusion
Most clone problems aren’t actually about the clone command — they’re about authentication, and the publickey error above accounts for the majority of “git clone doesn’t work” questions I see. Get your SSH key registered once and the command itself stays boring forever. Once the repo is on your machine, the next thing you’ll want is Git Add to start staging your changes.