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.
Git · Command
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
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.
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>]| Name | Type | Description |
|---|---|---|
<repository> | URL or path | The repository to copy, which may be remote. Accepts ssh, git, http(s), scp-like or local path/file:// forms, plus bundle files. |
<directory> | path | Target directory to create. If you leave it out, Git derives the name from the source. |
-b, --branch=<name> | string | Branch (or tag) for the new HEAD to point at, instead of the remote's HEAD. |
--depth=<depth> | integer | Makes a shallow clone that keeps only this many recent commits. |
--single-branch / --no-single-branch | flag | Fetches only the history leading to one branch tip. |
--filter=<filter-spec> | string | Makes a partial clone, e.g. blob:none or blob:limit=<size>. |
--bare | flag | Makes the target directory the repository itself, with no working tree. |
--mirror | flag | A bare clone that copies every ref and is set up to stay in sync with the source. |
-o, --origin=<name> | string | Name to use for the remote instead of origin. |
--recurse-submodules[=<pathspec>] | pathspec | Initializes and clones submodules once the clone finishes. |
-c, --config=<key>=<value> | string | Writes a config variable into the new repository before the fetch. |
#!/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 updateShows 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.
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.
A build pipeline uses --depth 1 --single-branch, so it downloads only the commit it is building and not years of history.
An admin runs clone --mirror to copy every ref, notes included, into a bare repository before moving to a new hosting provider.
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.
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.
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.
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 initgit fetchgit pullgit remotegit submodulegit sparse-checkoutgit rev-listgit bundle