Most developers run git clone on their first day with a project and then barely think about it again. The command copies a remote repository into a new local directory, brings along the commit history of every branch, and registers the source as a remote named origin.
The copy holds history for every branch but checks out only one, the branch the source repository’s HEAD points to (Git documentation, 2026).
The other branches arrive as remote-tracking references such as origin/main, so switching to one needs no second download.
What Is git clone in Git?

Running it once is enough for a project. Fetch and pull handle the syncing after that.
What you end up with is a complete repository in its own right. It stores its own history and manages its own files, so you can browse commits on a train with no signal and only reach back to the server when you fetch or push.
That peer relationship comes from Git being a distributed version control system, where no copy outranks another.
The source can be any remote repository reachable over ssh, http, https or the git protocol, or a repository on the same machine (Git manual).
A few things it gets confused with. A ZIP download carries no history and no way to push back, and a fork is a server-side copy on the hosting platform while a clone lives on your machine.
And git init is a different animal altogether. It creates an empty repository with no remote.
What Does git clone Create on Your Machine?

You get a target directory, and inside it a .git folder and a checked-out working tree. Git also sets up a remote called origin with its remote-tracking branches.
- The target directory takes its name from the source repository unless you pass another name.
- The .git directory holds the object database, the refs and the config, which together contain every commit.
- The working tree is the set of checked-out files you actually edit.
- Under refs/remotes/origin there is one reference per branch in the source, alongside the remote.origin.url and remote.origin.fetch settings.
You can list the remote-tracking branches with git branch --remotes. A plain git fetch afterwards updates all of them (Git 2.54.0 documentation, April 2026).
The name origin is a default, not a rule. The -o option or the clone.defaultRemoteName setting replaces it.
Which branch is checked out
Git creates exactly one local branch, forked from the branch the source repository’s HEAD points to.
Pass --branch and the named branch gets checked out instead of the remote HEAD branch. Hand it a tag and HEAD detaches at that commit.
Every other Git branch exists locally as a remote-tracking reference until you check it out.
GitHub Docs states that a clone pulls down every version of every file and folder as of that moment. Combine that with the one-local-branch rule and the result is full history on disk with a single branch in the working tree.
How to Run git clone, Step by Step

Run git clone followed by the repository URL. Git creates the directory, downloads the history and checks out the default branch in one go.
Basic syntax
The general form is git clone <repository> [<directory>], and the directory argument is optional.
- On GitHub, open the repository’s main page, click Code, and copy the HTTPS or SSH URL.
- Open a terminal (Terminal on macOS and Linux, Git Bash on Windows) and change to the folder that will hold the clone.
- Run
git clone https://github.com/OWNER/REPOSITORY.git. - Wait while Git receives and unpacks the objects. The “Cloning into” line names the directory it created.
- Move into the new folder and run
git statusandgit remote -vto confirm the branch and the origin URL.
That last check is a habit worth keeping. A quick git status shows which branch you landed on, and a wrong URL shows up at once in the remote listing.
GitHub CLI has a shorter form, gh repo clone OWNER/REPOSITORY. Leave out the owner and it defaults to the authenticated user (GitHub Docs).
A separate guide covers how to clone a Git repository as a task rather than a concept.
Choosing the target directory
With no directory argument, Git names the folder after the repository. So /path/to/repo.git becomes repo, and host.xz:foo/.git becomes foo.
To pick your own name, put it after the URL, as in git clone URL my-linux. An existing folder works only when it is empty.
Git refuses to clone into a folder that already holds files. The fix is a different path or an emptied folder.
A local path as the source behaves differently from a URL. Git copies HEAD, the objects and the refs directly and hardlinks the object files when it can, but a file:// URL skips those shortcuts (Git manual).
The local shortcut fails for repositories owned by another user, and --no-local forces the regular transport.
Clone Protocols and Authentication for Private Repositories

Git can clone over ssh, git, http and https, plus local paths. For a private repository the real choice is HTTPS with a personal access token or SSH with a key pair.
The Git manual points out that the git:// protocol does no authentication, so it cannot protect a private repository. It also notes that ftp and ftps are deprecated.
My rule of thumb is HTTPS for a one-off clone or a network that blocks port 22, and SSH for daily work across many repositories.
HTTPS with a personal access token
GitHub stopped accepting account passwords for Git operations on August 13, 2021 (GitHub Blog).
An HTTPS clone of a private repository now prompts for a username, and the token goes in the password field. Create a GitHub token in your account settings before the first clone.
- Git Credential Manager remembers the token so the prompt stops.
- With SAML SSO, a classic token has to be authorized for the organization before it works there.
- HTTPS URLs also work behind firewalls and proxies (GitHub Docs).
SSH with a key pair
SSH URLs use the scp-like form git@github.com:OWNER/REPOSITORY.git.
You generate the key pair locally and add only the public key to your account. This walkthrough on adding an SSH key to GitHub covers the account side.
- Git asks for the key passphrase on every clone unless ssh-agent holds the unlocked key.
- If port 22 is blocked, GitHub accepts SSH over the HTTPS port.
- Organizations with SAML SSO require the key to be authorized first.
- Setup takes longer than with HTTPS, though the prompts mostly disappear afterwards.
Which git clone Option Fits Which Job?

Pick the smallest clone that still supports the next command you plan to run. For a developer working in one reasonably sized repository, that is a plain full clone (GitHub engineering blog, December 2020).
| Option | What it copies | Use it when | Limitation |
|---|---|---|---|
--single-branch | History of one branch | The repository has many branches you will never touch | Later fetches update only that branch’s remote-tracking reference |
--depth=1 | Latest commit only | A build that deletes the repository afterward | History commands give different results |
--filter=blob:none | All commits and trees, file contents on demand | Daily work in a repository with heavy history | First blame or diff downloads blobs |
--recurse-submodules | The repository plus its submodules | The project nests other repositories | Ignored without a checkout |
--bare or --mirror | Repository data, no working tree | Servers and backups | No files to edit |
Blobless and treeless clones
On github.com and GitHub Enterprise Server 2.22 and later, two partial-clone filters work: --filter=blob:none and --filter=tree:0 (GitHub Blog, December 2020).
A blobless clone keeps every commit and tree and downloads file contents on demand, so git log -- path runs as fast as in a full clone. The first git blame or git diff on a file pulls the missing blobs.
A treeless clone keeps commits only. GitHub points to builds on Actions public runners as the fit, since the repository is thrown away after the build.
Treeless breaks on file-history requests. Something like git log -- path downloads root trees for almost every commit, and in repositories with submodules a plain git fetch requests a tree for every new commit. Setting fetch.recurseSubmodules to false avoids that.
The server can also deny the filter and send a full clone instead.
Shallow clones

GitHub’s engineers advise against shallow clones for developer use.
They do give you the fastest copy of the working directory at the tip commit, which is handy for a build that deletes the repository right after.
The downsides pile up quickly, though. git log and git merge-base return different results than in a full clone, and a fetch costs more. It can even pull almost the full history when someone branches below the shallow boundary.
For a continuous integration build that clones once and discards the repository, --depth=1 is a sound choice. On a laptop it is not.
The Git manual adds that --depth implies --single-branch unless --no-single-branch is given.
Bare and mirror clones
--bare makes the target directory itself the Git directory, with no working tree and no remote-tracking branches. --mirror implies bare and maps all refs, so a later git remote update overwrites them.
Use these for a repository that serves or backs up other copies, because a bare repository has nowhere to check out files. Pairing either with --recurse-submodules does nothing, since the manual states the option is ignored without a checkout.
git clone vs Fork, Pull, Fetch and ZIP Download

Clone copies a repository to your machine once. Fork copies it on the hosting platform, fetch and pull update an existing clone, and a ZIP download exports a snapshot of one branch, tag or commit.
| Method | What you get | Runs | Use it when |
|---|---|---|---|
| git clone | Full local repository with history | Once per repository | You will edit, commit or push |
| Fork | Separate repository on GitHub, linked to upstream | Once per project | You cannot push to the original |
| git fetch | New commits in remote-tracking branches | Whenever you want to look first | You want to inspect before integrating |
| git pull | Fetch plus integration into the current branch | Repeatedly | You want your branch current now |
| ZIP download | Snapshot of one branch, tag or commit | On demand | You need the files only |
Fork and clone together
A fork is a separate repository with its own settings, permissions, issues and pull requests, and it stays connected to the upstream repository (GitHub Docs).
The common contribution path starts with a fork on GitHub, then clones that fork, so origin points at your copy and not at the project. That path exists for projects where you cannot push to the original.
GitHub documents one access difference between the two. Removing someone from a private repository deletes their forks of it, while their local clones are retained.
Pull and fetch
Fetch downloads new commits into the remote-tracking branches and leaves your own branches alone. Pull runs fetch with the same arguments, then integrates the upstream branch into the current branch (Git manual).
The manual lists several integration options, and --ff-only is the default. The rest are --rebase, --no-rebase (which runs a merge) and --squash.
With --ff-only, a pull fails when the local branch has diverged from the remote branch, by design. Choosing between the other modes is the subject of a separate explainer on what git pull does.
ZIP download
GitHub generates ZIP and tarball snapshots with git archive for any branch, tag or commit (GitHub Docs).
Archives are built on request, cached for a while, then deleted and regenerated on the next request.
- An archive of a commit ID has the same file contents on every download, as long as the commit exists and the repository name is unchanged.
- An archive of a branch or tag changes when that branch or tag moves.
- The repository name becomes the root folder inside the archive.
So clone anything you will edit or push, fork repositories you cannot push to, and download a ZIP only for a one-time look at the files.
Why Does git clone Fail and How to Fix Each Error?

Most failures come down to a wrong URL, missing access, a non-empty target folder or a deleted default branch. The table maps each message to its fix.
| Error message | Cause | Fix |
|---|---|---|
| Repository not found | URL typo, or a private repository you cannot access | Copy the URL from the repository page and confirm owner, collaborator or team access |
| Permission denied (publickey) | SSH key not attached to your account | Test with ssh -T git@github.com, then add the key to your personal account |
| 401 or 403 over HTTPS | Missing token, wrong account or stale cached credentials | Use a personal access token, authorize it for SAML SSO, refresh cached credentials |
| destination path already exists and is not an empty directory | The target folder holds files | Clone into another folder or empty the target |
| remote HEAD refers to nonexistent ref | Default branch deleted on the host | An admin sets a new default branch, then check out a branch |
Wrong URL or remote after cloning
Typos cause the “Repository not found” error. GitHub Docs gives the example of cloning owner/repotile when the repository is really owner/repoti1e.
Copy the clone URL from the repository page instead of typing it.
For a clone that already exists with a bad origin, the git remote commands show and repair it. git remote -v lists the URL, and git remote set-url origin NEW-URL replaces it.
Missing default branch
The clone finishes, then Git warns that the remote HEAD refers to a nonexistent ref and checks out nothing. The default branch was deleted on GitHub.
- A repository administrator changes the default branch on GitHub.
- Run
git branch -ato list the remote-tracking branches. - Check out the branch you want, for example
git checkout new-main, which creates a tracking branch.
The last step is ordinary switching branches in Git, done inside the clone you already have.
Slow or oversized clones

Large repositories produce no error, only a long wait.
A full clone downloads every reachable commit, tree and blob, so history-heavy repositories take longest (GitHub Blog).
A blobless clone keeps full history and defers file contents. A shallow clone truncates history instead, which suits a one-off build.
Common Questions About git clone
Do I need to run git init before cloning?
No. git clone creates the directory and initializes the repository itself.
Running git init first backfires, because the hidden .git folder makes the target non-empty and Git refuses to clone into it.
Does cloning a repository change the original?
No. Cloning only reads from the source, and the new repository keeps its own history.
The original changes only when someone pushes to it, from your clone or any other.
Does git clone copy stashes, hooks and uncommitted changes?
None of them. Only committed objects and their branch and tag refs travel, so uncommitted edits and stashes stay with whoever made them.
Hooks are not cloned either. A new clone gets its hooks from the template directory, which the init.templateDir setting controls.
Can I clone just one folder of a repository?
Not directly, because clone always fetches repository data. The --sparse option limits the checkout to the top-level directory, and git sparse-checkout adds folders as you need them.
Pair it with --filter=blob:none to skip downloading contents of files you never check out.
How does git clone handle Git LFS files?
Git LFS stores large files as small pointer files in the repository.
With Git LFS installed, a clone downloads the real contents for files in the checked-out branch. Without it, you get pointer files only.
When a Shallow Clone Stops Being Enough
A shallow clone stops being enough when the work needs commits below the shallow boundary, which a clone made with --depth=1 never downloaded.
The fix is one command. git fetch --unshallow turns the repository into a complete one and removes every limit that shallow repositories carry (Git manual).
Run the command you need on a real path first, and unshallow when the results look truncated. If only file contents are missing, a blobless clone is the better thing to keep.
Unshallowing downloads the history that --depth skipped, so the saved time is spent anyway. A blobless clone spreads that cost across later file requests and needs a connection to the server for them.
This advice was verified in October 2026 against a git-clone manual last changed in Git 2.54.0 (April 2026). Git 2.55 and 2.56 left that manual unchanged. A new clone option would change it.
With the history complete, pushing to GitHub is the next step.
- How to Turn On Dark Mode in Notepad++ (Built-In, No Plugin) - October 3, 2026
- PostgreSQL Cheat Sheet - October 2, 2026
- How to Repair a Corrupt SQL Server Database Without Any Data Loss - October 2, 2026



