简体中文 ▾ 主题 ▾ 最新版本 ▾ git-clone 最新更新于 2.54.0

名称

git-clone - 克隆仓库到一个新目录

概要

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>]

描述

克隆一个仓库到一个新创建的目录,为被克隆仓库中的每个分支创建远程跟踪分支(使用 git branch --remotes 可见),并创建和检出一个初始分支,该分支分叉自被克隆仓库当前活动的分支。

克隆完成后,不带参数的普通 git fetch 将更新所有远程跟踪分支,而不带参数的 git pull 还会将远程 master 分支合并到当前的 master 分支(如果有的话)(当指定 --single-branch 时并非如此;见下文)。

此默认配置是通过在 refs/remotes/origin 下创建指向远程分支头部的引用,并初始化 remote.origin.urlremote.origin.fetch 配置变量来实现的。

选项

-l
--local

当要克隆的仓库位于本地计算机上时,此标志将绕过常规的“Git 感知”传输机制,通过复制 HEAD 以及 objects 和 refs 目录下的所有内容来克隆仓库。如果可能,将对 .git/objects/ 目录下的文件进行硬链接以节省空间。

如果仓库被指定为本地路径(例如 /path/to/repo),则这是默认行为,且 --local 基本上不起作用。如果仓库被指定为 URL,则此标志将被忽略(我们绝不会使用本地优化)。当指定了 /path/to/repo 时,指定 --no-local 将覆盖默认行为,转而使用常规的 Git 传输。

如果仓库的 $GIT_DIR/objects 含有符号链接或者是符号链接,则克隆将失败。这是一种安全措施,旨在防止通过解引用符号链接来无意中复制文件。

出于安全原因,此选项不适用于其他用户拥有的仓库,必须指定 --no-local 才能克隆成功。

注意:此操作可能会与对源仓库的并发修改产生竞态条件,类似于在修改 <src> 的同时运行 cp -r <src> <dst>

--no-hardlinks

强制从本地文件系统上的仓库进行克隆的过程复制 .git/objects 目录下的文件,而不是使用硬链接。如果您正在尝试备份您的仓库,这可能是期望的操作。

-s
--shared

当要克隆的仓库位于本地计算机上时,不使用硬链接,而是自动设置 .git/objects/info/alternates 与源仓库共享对象。生成的仓库一开始没有任何自己的对象。

注意
这是一个可能具有危险性的操作;除非您了解其作用,否则请勿使用它。如果您使用此选项克隆仓库,然后在源仓库中删除分支(或使用任何其他使现有提交变为未引用状态的 Git 命令),某些对象可能会变成未引用(或悬空)状态。这些对象可能会被自动调用 git maintenance run --auto 的常规 Git 操作(例如 git commit)清除。(参见 git-maintenance[1]。)如果这些对象被清除,而它们又被克隆的仓库所引用,那么克隆的仓库将会损坏。

请注意,在通过 --shared 克隆的仓库中运行不带 --local 选项的 git repack,会将源仓库的对象复制到克隆仓库的包(pack)中,从而失去 clone --shared 所带来的磁盘空间节省。不过,运行默认使用 --local 选项的 git gc 是安全的。

如果您想断开使用 --shared 克隆的仓库对其源仓库的依赖,只需运行 git repack -a 即可将源仓库中的所有对象复制到克隆仓库的包(pack)中。

--reference=<repository>
--reference-if-able=<repository>

如果参考仓库 <repository> 位于本地计算机上,则自动设置 .git/objects/info/alternates 以从该参考仓库 <repository> 获取对象。将现有仓库作为交替(alternate)仓库使用,需要从正在克隆的仓库中复制的对象就会更少,从而减少网络和本地存储开销。使用 --reference-if-able 时,如果目录不存在,将跳过并发出警告,而不是中止克隆。

注意
请参阅 --shared 选项的“注意”以及 --dissociate 选项。
--dissociate

仅借用通过 --reference 选项指定的参考仓库中的对象以减少网络传输,并在克隆完成后,通过为借用的对象制作必要的本地副本,来停止向它们借用。此选项也可用于从已从另一个仓库借用对象的仓库进行本地克隆的情况——新仓库将从同一个仓库借用对象,而此选项可用于停止这种借用关系。

-q
--quiet

静默操作。不向标准错误流报告进度。

-v
--verbose

详细输出运行过程。不影响向标准错误流报告进度状态。

--progress

当连接到终端时,默认情况下在标准错误流上报告进度状态,除非指定了 --quiet。即使标准错误流没有指向终端,此标志也会强制输出进度状态。

--server-option=<option>

使用协议版本 2 通信时,将给定的字符串发送到服务器。给定的字符串不得包含 NULLF 字符。服务器对服务器选项的处理(包括未知选项)是服务器特定的。当给出多个 --server-option=<option> 时,它们都会按照命令行上列出的顺序发送到另一端。当命令行上未给出 --server-option=<option> 时,将使用配置变量 remote.<name>.serverOption 的值。

-n
--no-checkout

克隆完成后不检出 HEAD

--no-reject-shallow
--reject-shallow

如果源仓库是浅仓库(shallow repository),则失败。配置变量 clone.rejectShallow 可用于指定默认值。

--bare

创建一个裸(bare) Git 仓库。也就是说,不是创建 <directory> 并将管理文件放在 <directory>/.git 中,而是使 <directory> 本身成为 $GIT_DIR。这显然暗示了 --no-checkout,因为没有地方可以检出工作树。此外,远程的分支头部会直接复制到对应的本地分支头部,而不会将它们映射到 refs/remotes/origin/。使用此选项时,既不会创建远程跟踪分支,也不会创建相关的配置变量。

--sparse

采用稀疏检出(sparse-checkout),最初只包含顶级目录中的文件。git-sparse-checkout[1] 命令可用于根据需要扩展工作区。

--filter=<filter-spec>

使用部分克隆(partial clone)功能,并请求服务器根据给定的对象过滤器发送可达对象的子集。使用 --filter 时,提供的 <filter-spec> 将用作部分克隆的过滤器。

如果使用 --filter=auto,过滤规范将通过 promisor-remote 协议(参见 gitprotocol-v2[5]),通过结合服务器针对客户端接受的 promisor 远程仓库所宣告的过滤规范,自动确定(参见 git-config[1] 中的 promisor.acceptFromServer 配置选项)。这允许服务器为可用的 promisor 远程仓库建议最佳过滤器。

与其他过滤规范一样,"auto" 值会保留在配置中。这确保了未来的拉取(fetch)将继续适应服务器当前的推荐。

有关所有其他可用过滤器规格的详细信息,请参见 git-rev-list[1] 中的 --filter=<filter-spec> 选项。

例如,--filter=blob:none 将过滤掉所有 blob(文件内容),直到 Git 需要它们。此外,--filter=blob:limit=<size> 将过滤掉所有大小至少为 <size> 的 blob。

--also-filter-submodules

同时将部分克隆过滤器应用到仓库中的任何子模组(submodule)。需要 --filter--recurse-submodules。可以通过设置 clone.filterSubmodules 配置选项默认开启此功能。

--mirror

设置源仓库的镜像。这隐含了 --bare。与 --bare 相比,--mirror 不仅将源仓库的本地分支映射到目标仓库的本地分支,它还会映射所有引用(包括远程跟踪分支、notes 等),并设置一个引用规范(refspec)配置,使得所有这些引用都会被目标仓库中的 git remote update 覆盖。

-o<name>
--origin=<name>

使用 <name>,而不是使用远程名称 origin 来跟踪上游仓库。覆盖配置中的 clone.defaultRemoteName

-b<name>
--branch=<name>

将新创建的 HEAD 指向 <name> 分支,而不是克隆仓库的 HEAD 所指向的分支。在非裸仓库中,这就是将被检出的分支。--branch 也可以接受标签,并在生成的仓库中使 HEAD 分离(detached)到该提交。

--revision=<rev>

创建一个新仓库,并获取通往给定修订版本 <rev> 的历史记录(不获取其他内容),而不创建任何远程跟踪分支,也不创建任何本地分支,并将 HEAD 分离到 <rev>。参数可以是一个剥解为提交的引用名称(例如 refs/heads/mainrefs/tags/v1.0),或者一个十六进制的对象名称。此选项与 --branch--mirror 不兼容。

-u<upload-pack>
--upload-pack=<upload-pack>

当通过 ssh 访问要克隆的仓库时,为在另一端运行的命令指定一个非默认路径。

--template=<template-directory>

指定将要使用模板的目录;(参见 git-init[1] 的“模板目录”部分。)

-c<key>=<value>
--config=<key>=<value>

在新创建的仓库中设置一个配置变量;这在仓库初始化后立即生效,但在获取远程历史记录或检出任何文件之前。<key> 的格式与 git-config[1] 所期望的相同(例如,core.eol=true)。如果为同一个键指定了多个值,每个值都将被写入配置文件。这使得向 origin 远程仓库安全地添加额外的拉取引用规范(fetch refspecs)成为可能。

由于当前实现的限制,某些配置变量直到初始拉取和检出后才会生效。已知不生效的配置变量是:remote.<name>.mirrorremote.<name>.tagOpt。请改用对应的 --mirror--no-tags 选项。

--depth=<depth>

创建一个浅(shallow)克隆,其历史记录被截断为指定的提交次数。隐含了 --single-branch,除非指定了 --no-single-branch 以获取所有分支尖端(tips)附近的历史记录。如果您想浅克隆子模组,请同时传递 --shallow-submodules

--shallow-since=<date>

创建一个包含指定时间之后历史记录的浅克隆。

--shallow-exclude=<ref>

创建一个排除从指定远程分支或标签可达的提交的历史记录的浅克隆。此选项可以指定多次。

--single-branch
--no-single-branch

仅克隆指向单个分支尖端的历史记录,该分支要么由 --branch 选项指定,要么是远程仓库的 HEAD 指向的主分支。后续向生成仓库进行的拉取(fetch)将仅更新最初克隆时使用此选项的分支的远程跟踪分支。如果在进行 --single-branch 克隆时,远程的 HEAD 未指向任何分支,则不会创建远程跟踪分支。

--tags
--no-tags

控制是否克隆标签。指定 --no-tags 时,该选项将通过设置 remote.<remote>.tagOpt=--no-tags 配置而永久生效。这确保了未来的 git pullgit fetch 不会跟随任何标签。后续显式的标签获取仍然有效(参见 git-fetch[1])。

默认情况下会克隆标签,因此传递 --tags 通常不起作用,除非它取消了之前的 --no-tags

可与 --single-branch 结合使用,以克隆并维护一个除了单个克隆分支外没有其他引用的分支。这在例如为搜索索引维护某些仓库默认分支的最小克隆时非常有用。

--recurse-submodules[=<pathspec>]

创建克隆后,根据提供的 <pathspec> 初始化并克隆其中的子模组。如果未提供 =<pathspec>,则初始化并克隆所有子模组。对于由多个条目组成的路径规格(pathspec),可以多次给出此选项。生成的克隆将 submodule.active 设置为提供的路径规格,如果未提供路径规格,则设置为 "."(表示所有子模组)。

子模组将使用其默认设置进行初始化和克隆。这相当于在克隆完成后立即运行 git submodule update --init --recursive <pathspec>。如果克隆的仓库没有工作区/未检出(即,如果指定了 --no-checkout/-n--bare--mirror 中的任何一个),则此选项将被忽略。

--shallow-submodules
--no-shallow-submodules

所有克隆的子模组都将是深度为 1 的浅克隆。

--remote-submodules
--no-remote-submodules

所有克隆的子模组都将使用子模组远程跟踪分支的状态来更新子模组,而不是父项目(superproject)中记录的 SHA-1。这相当于将 --remote 传递给 git submodule update

--separate-git-dir=<git-dir>

而不是将克隆的仓库放在它应该在的位置,而是将其放在指定的目录中,然后在那里制作一个与文件系统无关的 Git 符号链接。结果是 Git 仓库可以与工作区分离。

--ref-format=<ref-format>

为仓库指定给定的引用存储格式。有效值为

files

用于带 packed-refs 的松散文件。这是默认格式。

reftable

用于 reftable 格式。

-j<n>
--jobs=<n>

同时获取的子模组数量。默认值为 submodule.fetchJobs 选项。

<repository>

要克隆的(可能是远程的)<repository>。有关指定仓库的更多信息,请参见下面的 GIT URLS 部分。

<directory>

要克隆入的新目录的名称。如果未显式指定 <directory>,则使用源仓库的“人性化”部分(对于 /path/to/repo.gitrepo,对于 host.xz:foo/.gitfoo)。只有当目录为空时,才允许克隆到现有目录中。

--bundle-uri=<uri>

在从远程拉取之前,从给定的 <uri> 获取一个包(bundle)并将数据解包到本地仓库中。该包中的引用将存储在隐藏的 refs/bundle/* 命名空间下。此选项与 --depth--shallow-since--shallow-exclude 不兼容。

GIT URLS

通常,URL 包含有关传输协议、远程服务器地址和仓库路径的信息。根据传输协议,其中一些信息可能不存在。

Git 支持 ssh、git、http 和 https 协议(此外,ftp 和 ftps 也可用于获取,但这效率低下且已弃用;请勿使用它们)。

原生传输(即 git:// URL)不进行身份验证,在不安全的网络上应谨慎使用。

可以使用以下语法:

  • ssh://[<user>@]<host>[:<port>]/<path-to-git-repo>

  • git://<host>[:<port>]/<path-to-git-repo>

  • http[s]://<host>[:<port>]/<path-to-git-repo>

  • ftp[s]://<host>[:<port>]/<path-to-git-repo>

ssh 协议还可以使用另一种类似 scp 的语法:

  • [<user>@]<host>:/<path-to-git-repo>

仅当第一个冒号之前没有斜杠时,此语法才会被识别。这有助于区分包含冒号的本地路径。例如,本地路径 foo:bar 可以指定为绝对路径或 ./foo:bar 以避免被误解为 ssh url。

ssh 和 git 协议还支持 ~<username> 扩展

  • ssh://[<user>@]<host>[:<port>]/~<user>/<path-to-git-repo>

  • git://<host>[:<port>]/~<user>/<path-to-git-repo>

  • [<user>@]<host>:~<user>/<path-to-git-repo>

对于 Git 本身也支持的本地仓库,可以使用以下语法

  • /path/to/repo.git/

  • file:///path/to/repo.git/

这两种语法大部分是等价的,除了前者暗示了 --local 选项。

git clonegit fetchgit pull(但不是 git push)也将接受一个合适的 bundle 文件。参见 git-bundle[1]

当 Git 不知道如何处理某种传输协议时,它会尝试使用 remote-<transport> 远程助手(如果存在)。要显式请求一个远程助手,可以使用以下语法

  • <transport>::<address>

其中 <address> 可以是路径、服务器和路径,或者是特定远程辅助工具可识别的任意类 URL 字符串。有关详细信息,请参阅 gitremote-helpers[7]

如果存在大量名称相似的远程仓库,并且您想为它们使用不同的格式(以便您使用的 URL 将被重写为可用的 URL),您可以创建以下形式的配置节:

	[url "<actual-url-base>"]
		insteadOf = <other-url-base>

例如,有了这个:

	[url "git://git.host.xz/"]
		insteadOf = host.xz:/path/to/
		insteadOf = work:

“work:repo.git”或“host.xz:/path/to/repo.git”这样的 URL 在任何接受 URL 的上下文中都将被重写为“git://git.host.xz/repo.git”。

如果只想重写推送的 URL,可以创建以下形式的配置节:

	[url "<actual-url-base>"]
		pushInsteadOf = <other-url-base>

例如,有了这个:

	[url "ssh://example.org/"]
		pushInsteadOf = git://example.org/

像“git://example.org/path/to/repo.git”这样的 URL 将被重写为“ssh://example.org/path/to/repo.git”用于推送,但拉取仍将使用原始 URL。

示例

  • 从上游克隆

    $ git clone git://git.kernel.org/pub/scm/.../linux.git my-linux
    $ cd my-linux
    $ make
  • 制作一个从当前目录借用的本地克隆,而不进行检出

    $ git clone -l -s -n . ../copy
    $ cd ../copy
    $ git show-branch
  • 在从现有本地目录借用的同时,从上游进行克隆

    $ git clone --reference /git/linux.git \
    	git://git.kernel.org/pub/scm/.../linux.git \
    	my-linux
    $ cd my-linux
  • 创建一个裸仓库以将您的更改发布到公共场所

    $ git clone --bare -l /home/proj/.git /pub/scm/proj.git
  • 克隆另一个用户的本地仓库

    $ git clone --no-local /home/otheruser/proj.git /pub/scm/proj.git

配置

本节中以下所有内容均从 git-config[1] 文档中选择性地包含。内容与彼处相同:

init.templateDir

指定复制模板的目录。(参见 git-init[1] 的“模板目录”部分。)

init.defaultBranch

允许覆盖默认分支名称,例如在初始化新仓库时。

init.defaultObjectFormat

允许覆盖新存储库的默认对象格式。请参阅 git-init[1] 中的 --object-format=。命令行选项和 GIT_DEFAULT_HASH 环境变量都优先于此配置。

init.defaultRefFormat

允许覆盖新存储库的默认 ref 存储格式。请参阅 git-init[1] 中的 --ref-format=。命令行选项和 GIT_DEFAULT_REF_FORMAT 环境变量都优先于此配置。

init.defaultSubmodulePathConfig

一个布尔值,指定 git initgit clone 是否应自动将 extensions.submodulePathConfig 设置为 true。这允许所有新仓库自动使用子模块路径扩展。未设置时默认为 false

clone.defaultRemoteName

克隆仓库时要创建的远程仓库的名称。默认值为 origin。可以通过传递命令行选项 --origin 来覆盖它。

clone.rejectShallow

如果仓库是浅仓库,则拒绝克隆它;这可以通过在命令行上传递 --reject-shallow 选项来覆盖。

clone.filterSubmodules

如果提供了部分克隆过滤器(参见 git-rev-list[1] 中的 --filter)并且使用了 --recurse-submodules,则同样将过滤器应用到子模组。

GIT

Git[1] 套件的一部分