Git

How to Clone a Git Repository in Simple Steps

How to Clone a Git Repository in Simple Steps

Open a terminal and run git clone with the repository URL after it. Git makes a new local folder, copies the project in, and saves the source as a remote named origin.

It works with GitHub, GitLab, Bitbucket and Azure DevOps, over HTTPS or SSH. Most people reach for it when they join a project that already lives somewhere else.

Don’t think of it as a Subversion checkout. By default Git pulls down every version of every file in the history (Pro Git), so the first transfer is the big one. Later fetches only bring in new commits.

How to clone a Git repository step by step

YouTube player

Run git clone and the URL, and you end up with a folder that holds the whole project.

  1. Check that Git is installed with git --version.
  2. Copy the clone URL from the repository page on GitHub, GitLab, or Bitbucket.
  3. Open a terminal and move to the folder that should hold the project.
  4. Run git clone <url> and wait for the transfer to finish.
  5. Move into the new folder with cd and start working.

The syntax is git clone <repository> [<directory>], and that second argument is optional. It sets the name of the target folder.

Leave it out and Git names the folder after the repository. Cloning libgit2 gives you a libgit2 directory, while git clone https://github.com/libgit2/libgit2 mylibgit gives you mylibgit instead (Pro Git, git-scm.com).

Git prints a “Cloning into” line as soon as the transfer starts. On a big project it sits there for a while. That’s normal.

If the version check in step 1 throws an error, install Git first, since the clone command won’t run without it.

Windows users get the Git Bash terminal with Git for Windows, and it takes the same commands as a macOS or Linux shell.

What does git clone create on your machine?

You get a complete local repository. Every commit from the remote comes along, plus a hidden .git directory and a working tree for whichever branch the remote has active. It is not a snapshot of the latest files.

Why is GitHub the heart of open source?

Uncover GitHub statistics: developer community growth, repository trends, collaboration patterns, and the platform that powers modern software development.

Explore GitHub Data →

Subversion users expect a checkout to fetch one working copy. Git receives a full copy of nearly all the data the server holds (Pro Git).

  • The project files of the checked-out branch, ready to edit
  • A .git directory holding the object database, the configuration and the entire history
  • A remote called origin that points at the URL you cloned from
  • One remote-tracking branch for each remote branch, plus a single new local branch that gets checked out

Git files the remote under the remote name origin by default, through the remote.origin.url and remote.origin.fetch settings. The clone.defaultRemoteName setting or the --origin flag renames it, according to the git-clone manual.

The remote-tracking branches sit under refs/remotes/origin. They record where each branch stood on the remote repository when you cloned, and a plain git fetch updates them later.

To check the result, run git remote -v for the fetch and push URLs and git branch --remotes for the tracking branches.

Bare clones are the exception. There’s no working tree, and the git-clone manual states that neither remote-tracking branches nor the related configuration variables get created.

Looking to sharpen your Git skills? Branching, merging, rebasing, and everything else you need - including git rebase, git stash, and commit workflows - is on one page in the Git Cheat Sheet.

HTTPS or SSH: which clone URL should you use?

HTTPS is quicker to set up. SSH pays off on a machine you clone from every day. Both fetch the same repository, and the only real difference is how Git proves who you are.

ProtocolExample URLAuthenticationBest for
HTTPShttps://github.com/user/repo.gitToken or credential helperFirewalls, proxies, first clones
SSHgit@github.com:user/repo.gitSSH key pairDaily work on a trusted machine
Local path../projectFilesystem permissionsCopying a repository on the same machine

A local path needs no network and no credentials, only read access to the source folder.

HTTPS in practice

HTTPS gets through firewalls and proxies, needs no key, and is available on every repository whatever its visibility (GitHub Docs).

The annoyance shows up with private repositories, which need a token or a credential helper. Without a helper, Git asks for your credentials on every single clone.

SSH in practice

SSH needs a key pair on your computer, and only the public half goes to your account on the host (GitHub Docs). The private key stays local, and once it sits in ssh-agent the clone runs without a prompt.

▶ GIT EXPLAINED

If you commit, branch, or merge code every day, it helps to know how Git came to be. This video covers how Linus Torvalds created Git in just 10 days after a license dispute and explains how its data model actually works.

Linus Torvalds Built Git in Days Out of Spite
Built in 10 Days Out of Spite. Git and its data model explained in plain language.

The catch is the network. When port 22 is closed, GitHub Docs point to SSH over the HTTPS port as a fallback, and on some networks that fails too, which leaves HTTPS as the only option.

Most developers end up with both. HTTPS for throwaway clones, SSH for the repositories they push to daily.

How to authenticate when cloning a private repository

A private repository needs a credential, either a personal access token over HTTPS or an SSH key pair. Your account password no longer works on GitHub.com.

GitHub stopped accepting account passwords for Git operations on August 13, 2021, and requires token-based authentication, SSH keys included (GitHub Changelog, 2021).

Clone with a personal access token

Generate a token in your account settings, run the HTTPS clone, and paste the token when Git asks for a password. The walkthrough on getting a GitHub token covers the settings screens.

GitLab documents a one-line form that embeds the token: git clone https://<username>:<token>@gitlab.example.com/tanuki/awesome_project.git.

It has a cost, though. Git records the cloned URL in remote.origin.url, so the token stays in .git/config and travels with every copy of the folder.

Clone with an SSH key

  1. Generate a key pair with ssh-keygen.
  2. Add the public key to your account on the host, as in the guide on adding an SSH key to GitHub.
  3. Load the private key into ssh-agent so the passphrase is requested once per session.
  4. Clone with the SSH URL, for example git@github.com:user/repo.git.

Store credentials with a credential helper

As of October 2026, GitHub Docs recommend GitHub CLI or Git Credential Manager for remembering HTTPS credentials.

  • Git Credential Manager defaults to the macOS Keychain and the Windows Credential Manager (GCM documentation)
  • GitHub CLI stores your Git credentials if you choose HTTPS during login
  • git credential-cache keeps them in memory for 900 seconds by default
  • The plaintext store saves them unprotected in a file, which GCM itself marks as insecure

How to clone with GitHub CLI, GitHub Desktop or Visual Studio Code

All of these run the same clone underneath, so the result matches a terminal clone. Use whichever one you already have open.

GitHub CLI

The command is gh repo clone OWNER/REPO, with an optional directory after it (GitHub CLI manual). Extra git clone flags go after a double dash, as in gh repo clone cli/cli -- --depth=1.

Leave out OWNER/ and it defaults to your own account. The protocol follows the git_protocol setting unless you pass a full URL. Cloning a fork also adds the parent repository as a remote named upstream.

Authenticate once with gh auth login and every clone after that skips the URL copying. It suits anyone already using GitHub CLI for pull requests.

GitHub Desktop

The clone options on a GitHub repository page include Open with GitHub Desktop, which clones the project into the app. GitHub Docs name it as the way to clone without authenticating on the command line, so a newcomer can clone through the GitHub Desktop app and skip the token step.

Visual Studio Code

VS Code clones from the Source Control view or the Command Palette, and both routes run the same Git command underneath.

  • Select Clone Repository in Source Control, or run Git: Clone from the Command Palette
  • Paste a URL, or pick Clone from GitHub and sign in to browse your repositories
  • Choose a parent folder, then open the cloned project

A public repository cloned by URL generally needs no sign-in (VS Code documentation). After the clone, a Workspace Trust dialog asks whether you trust the folder, and the answer matters for code you didn’t write.

GitLab, Bitbucket and Azure DevOps

GitLab clones over SSH or HTTPS and names the folder after the repository. The GitLab for VS Code extension adds its own Git: Clone command for GitLab projects (GitLab Docs).

Bitbucket and Azure DevOps each show their own clone URL on the repository page, and the git clone command stays the same.

How to clone a specific branch or into a named folder

Add --branch <name> to check out a branch other than the remote’s default. Put a folder name at the end of the command to choose where the files land.

Here are both in one line: git clone --branch release-2 https://github.com/user/repo.git my-copy

  • --branch points the new HEAD at that branch, and in a non-bare repository it’s the branch that gets checked out
  • --single-branch fetches only the history leading to one branch tip, and later fetches update only that remote-tracking branch
  • The folder argument names the target directory, and a dot clones into the current folder, which has to be empty

Without --single-branch, Git still downloads every branch. The --branch flag only changes which one gets checked out.

Passing --depth switches single-branch on automatically, unless --no-single-branch is given (git-clone manual).

The same flag accepts a tag name. A tag isn’t a branch, so the clone lands in a detached HEAD state at the tagged commit, per the git-clone manual.

Commits made there belong to no branch. Run git switch -c fix-login straight after the clone to create a new branch before touching any file.

Which clone type fits: full, shallow, partial or sparse?

A full clone suits daily development and a shallow clone suits throwaway builds. Blobless partial clones help with very large repositories, and sparse checkout makes sense when only a few directories matter. Get it wrong and you pay in download time or in missing history.

Clone typeFlagAdvantageLimitation
FullnoneEvery commit, tree, and file available offlineSlowest start on large repositories
Shallow–depth 1Smallest transfer, latest commit onlyHistory-dependent commands stop at the cut-off
Partial–filter=blob:noneFull commit history, file contents on demandNeeds the server for later checkouts
Sparse–sparseOnly chosen directories in the working treeDoes not shrink the download on its own

Shallow clones

The GitHub Blog (December 2020) advises shallow clones only for builds that delete the repository afterwards.

A later git fetch inside a shallow clone can pull down an almost complete history, depending on how others contribute, which defeats the purpose.

They fit continuous integration builds that compile once and discard the folder. Anything that walks past the truncated history breaks, and --depth quietly implies --single-branch too.

Partial clones

The --filter option tells the server to hold back objects until Git needs them. --filter=blob:none omits all file contents, while --filter=blob:limit=1m omits only files of 1 MB or larger (GitLab Docs, which demonstrates both on its www-gitlab-com repository).

  • GitHub.com supports blobless and treeless filters (GitHub Blog)
  • Commands such as git checkout and git blame download missing blobs when they run
  • No network means no blobs

Blobless keeps every commit and tree, which is why it suits ongoing development better than a shallow clone.

Sparse checkout

  1. Clone with git clone --filter=blob:none --sparse <url>.
  2. Choose the directories with git sparse-checkout set data --cone.

That pair comes straight from the GitLab documentation, and the --filter half matters. Sparse checkout alone only fills the working tree, so the download stays full size.

Bare and mirror clones

A bare repository has no working tree, so nobody edits files in it.

--mirror implies --bare and also maps every ref, including remote-tracking branches and notes, which makes it the right option for a full backup copy (git-clone manual).

How to clone a repository with submodules and Git LFS files

Add --recurse-submodules and Git clones the parent repository and its submodules in one command. Git LFS files need the LFS extension installed before the clone, or the working tree fills up with pointer files.

Clone with submodules

A submodule embeds another repository at a pinned commit, and after a plain clone its folder stays empty. The flag is equivalent to running git submodule update --init --recursive right after the clone, and nested submodules come along automatically (git-clone manual, Pro Git).

  • git clone --recurse-submodules <url> covers the standard case
  • Add --shallow-submodules to give every submodule a depth of 1
  • Add --filter with --also-filter-submodules to apply a partial clone filter to them too
  • Forgot the flag? Run git submodule update --init --recursive inside the clone

The --also-filter-submodules option requires both --filter and --recurse-submodules, or Git rejects the command.

Clone repositories that use Git LFS

Git LFS keeps small pointer files in the repository and stores the large files somewhere else. Without git lfs install, a clone leaves those pointers in the working tree, and git lfs pull swaps them for the real files (Git LFS FAQ).

To skip the download, set GIT_LFS_SKIP_SMUDGE=1 before the clone and the pointers stay put. Microsoft’s vscode-docs repository stores its images in Git LFS and documents exactly this, followed by git lfs pull -I "docs/nodejs" to fetch one folder.

Windows has a limit worth knowing. Git before 2.34 can’t handle working-tree files over 4 GiB through smudge and clean filters such as Git LFS (Git LFS FAQ). Update Git, or skip the smudge step and run git lfs pull afterwards.

Why does git clone fail, and how do you fix it?

A failed clone usually traces back to a wrong credential, a missing SSH key, a wrong or inaccessible URL, a target folder that isn’t empty, or a default branch that was deleted on the remote.

Error messageUsual causeFix
Authentication failedAccount password used, or outdated cached credentialsUse a token, then clear the stale cache entry
Permission denied (publickey)No key loaded, key not on the account, or wrong SSH userTest with ssh -T git@github.com, then add the key
Repository not foundTypo in the URL, or no access to a private repositoryCopy the URL from the repository page, check permissions
Destination path already exists and is not an empty directoryTarget folder already holds filesPick another folder name or empty the folder
Remote HEAD refers to nonexistent refDefault branch deleted on the remoteA repository admin sets a new default branch

Cached incorrect or outdated entries in Windows Credential Manager make Git fail against GitHub. Deleting the GitHub entry there forces a fresh prompt (GitHub Docs).

GitHub requires every SSH connection, remote URLs included, to use the “git” user, so a URL built with your own username fails. When the test passes but the clone doesn’t, ssh-add -l shows whether the agent holds a key at all.

“Repository not found” is one message for two situations, a repository that doesn’t exist and a private one you can’t see. Check the spelling first, then the access rights, then the SSH test.

Git Clone FAQ

What is the difference between a clone and a fork?

A clone is a local copy on your computer. A fork is a copy of the repository under your own account on the hosting platform, such as GitHub.

Contributors usually fork first, then clone the fork.

Is git clone the same as git pull?

No. Git clone creates a new local repository once, while git pull updates an existing one by fetching new commits and merging them into the current branch.

How does git clone differ from git init?

Git init starts an empty repository in a local folder, with no history and no remote. Git clone copies an existing repository, history included, and sets up the origin remote for you.

Is downloading a ZIP file the same as cloning?

No. GitHub’s ZIP download delivers a snapshot of the files at one branch, tag, or commit, not the entire history, so it carries no .git directory and no remote to fetch from later.

Can you change the remote URL after cloning?

Yes. Run git remote set-url origin <new-url>, then confirm the change with git remote -v.

This switches an existing clone between HTTPS and SSH without cloning again.

How do you turn a shallow clone into a full clone?

Run git fetch --unshallow inside the clone to download the missing history. To add only part of it, git fetch --deepen=<n> extends the history by that many commits.

Does git clone work the same on Windows, macOS and Linux?

Yes. The command and its flags are identical, because Git defines them, not the operating system.

Only the terminal differs. Git Bash or PowerShell on Windows, Terminal on macOS, any shell on Linux.

Keeping a New Clone in Sync With Its Remote

A fresh clone stays safe to edit if you do a few things in a set order. Identity first, then a branch, then a fetch. Each step removes a problem the next one would otherwise inherit.

  • Set user.name and user.email
  • Branch off before the first edit
  • Fetch, inspect, then merge

Commits record the name and email stored in git config, so a missing identity stamps your first commits with the wrong author.

A working branch keeps the default branch identical to the remote, so later updates apply to it without conflicts.

Fetching comes before pulling because git fetch only moves the remote-tracking branches, while git pull adds a merge into the current branch (git-clone manual). The price is one extra command per update, in return for seeing incoming commits before they touch your files.

Bogdan Sandu

Stay sharp. Ship better code.

Every week: one curated article, one tool worth knowing, one tip you can use tomorrow. No noise, no padding.