Skip to content
masterclass Buddy

Git · Command

git clone

git clone copies an existing repository into a new directory. It sets up remote-tracking branches for every branch in the source and checks out a starting branch based on the source's active branch.

Last updated

How it works

Clone sets up a new repository, records the source as a remote (called origin by default) and downloads its objects and refs. Each remote branch head gets a ref under refs/remotes/origin. Clone also writes remote.origin.url and remote.origin.fetch into the config, which is why a later plain git fetch or git pull with no arguments knows where to go. Options change how much gets copied: history depth, single branch, object filters, bare or mirror layout and submodules. Other options control how objects are stored, such as hardlinks, alternates or a separate git dir.

Syntax

git clone [--template=<template-directory>] [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror] [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>] [--dissociate] [--separate-git-dir <git-dir>] [--depth <depth>] [--[no-]single-branch] [--[no-]tags] [--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules] [--[no-]remote-submodules] [--jobs <n>] [--sparse] [--[no-]reject-shallow] [--filter=<filter-spec> [--also-filter-submodules]] [--] <repository> [<directory>]

Parameters

NameTypeDescription
<repository>URL or pathThe repository to copy, which may be remote. Accepts ssh, git, http(s), scp-like or local path/file:// forms, plus bundle files.
<directory>pathTarget directory to create. If you leave it out, Git derives the name from the source.
-b, --branch=<name>stringBranch (or tag) for the new HEAD to point at, instead of the remote's HEAD.
--depth=<depth>integerMakes a shallow clone that keeps only this many recent commits.
--single-branch / --no-single-branchflagFetches only the history leading to one branch tip.
--filter=<filter-spec>stringMakes a partial clone, e.g. blob:none or blob:limit=<size>.
--bareflagMakes the target directory the repository itself, with no working tree.
--mirrorflagA bare clone that copies every ref and is set up to stay in sync with the source.
-o, --origin=<name>stringName to use for the remote instead of origin.
--recurse-submodules[=<pathspec>]pathspecInitializes and clones submodules once the clone finishes.
-c, --config=<key>=<value>stringWrites a config variable into the new repository before the fetch.

Key points

  • If you don't give a target directory, Git takes the name from the source path. For example, /path/to/repo.git becomes repo.
  • --depth makes a shallow clone that keeps only the last N commits. It also turns on --single-branch unless you pass --no-single-branch.
  • With --single-branch, later fetches keep updating only the one branch you cloned. Other remote branches don't show up unless you change the fetch refspec.
  • --filter makes a partial clone. For example, blob:none skips file contents until Git actually needs them, which keeps the first download small.
  • --branch also accepts a tag name. In that case the new repository starts with a detached HEAD on that tag's commit.
  • --revision fetches only the history behind one ref or commit hash and detaches HEAD there. It creates no branches, and you can't combine it with --branch or --mirror.
  • --no-tags is permanent: it saves a tagOpt setting so later fetches and pulls skip tags too. Pair it with --single-branch for the smallest possible clone.

Common mistakes

  • Cloning into a directory that already exists only works if that directory is empty.
  • --shared borrows objects from the source repository. If the source later deletes branches and garbage collection prunes those objects, the clone can become corrupt.
  • git:// URLs have no authentication, so be careful using them on untrusted networks.
  • Some settings passed with -c only take effect after the first fetch, for example remote.<name>.mirror and tagOpt. Use --mirror and --no-tags for those instead.

Example: Fast, lightweight clones for CI and day-to-day work

#!/usr/bin/env bash
set -euo pipefail

# Standard clone into a custom directory name
git clone https://github.com/git/git.git my-git

# CI: newest commit of one branch only, with submodules also shallow
git clone --depth 1 --branch main --recurse-submodules --shallow-submodules \
  https://github.com/git/git.git ci-build

# Blobless partial clone: full history, file contents fetched on demand
git clone --filter=blob:none https://github.com/git/git.git git-blobless

# Bare mirror for a backup or a server copy
git clone --mirror https://github.com/git/git.git git-backup.git

# Later, refresh the mirror
git -C git-backup.git remote update

Shows a regular clone, a shallow CI clone with submodules, a blobless partial clone, and a mirror that you keep up to date with git remote update.

When to use it

Starting work on a project

A new team member clones the team repo over SSH. They can then branch, commit and push right away, because origin is already set up.

Fast CI checkouts

A build pipeline uses --depth 1 --single-branch, so it downloads only the commit it is building and not years of history.

Backup or migration mirror

An admin runs clone --mirror to copy every ref, notes included, into a bare repository before moving to a new hosting provider.

Working in a huge monorepo

A developer combines --filter=blob:none with --sparse, so the first checkout has only top-level files. They then add the directories they need with git sparse-checkout.

Interview questions

QWhat is the difference between git clone --bare and git clone --mirror?

Both make a repository with no working tree. --bare copies the remote's branch heads straight into local branches and creates no remote-tracking branches or remote config. --mirror goes further: it copies every ref, including remote-tracking branches and notes. It also sets up a refspec so that git remote update overwrites all of them to match the source.

Follow-up: Which one would you use for a backup that has to stay in sync? --mirror, because a plain git remote update then copies every ref from the source, deletions included. A bare clone has no fetch refspec set up to do that.

QHow do you clone a repository that has submodules and get the submodule contents too?

Pass --recurse-submodules, with an optional pathspec. After the main clone finishes, it does the same as running git submodule update --init --recursive. It also sets submodule.active to that pathspec, or to "." (all submodules) if you didn't give one. --jobs sets how many submodules download at once.

Follow-up: Why might the submodules still be empty after a clone with --recurse-submodules? Because the option is ignored when there is no working tree, i.e. with --no-checkout, --bare or --mirror.

QHow is cloning a local path different from cloning a file:// URL?

With a plain path, Git uses --local by default: it skips the normal transport, copies HEAD, objects and refs directly, and hardlinks object files when it can. A file:// URL goes through the regular Git transport instead. You can force that for a path with --no-local, and you must do so if another user owns the source repository.

Follow-up: When would you use --no-hardlinks? When the clone is a backup. Hardlinked object files share storage with the source, so damage to the source's disk would hit both copies.

  • git init
  • git fetch
  • git pull
  • git remote
  • git submodule
  • git sparse-checkout
  • git rev-list
  • git bundle

Source: Git - git-clone Documentation. Checked 2026-11-02.