设置和配置
获取和创建项目
基本快照
分支和合并
共享和更新项目
检查和比较
修补
调试
邮件
外部系统
服务器管理
指南
管理
底层命令
- 2.47.0 无更改
- 2.46.2 09/23/24
- 2.45.1 → 2.46.1 无更改
- 2.45.0 04/29/24
- 2.44.1 → 2.44.2 无更改
- 2.44.0 02/23/24
- 2.43.1 → 2.43.5 无更改
- 2.43.0 11/20/23
- 2.42.1 → 2.42.3 无更改
- 2.42.0 08/21/23
- 2.41.1 → 2.41.2 无更改
- 2.41.0 06/01/23
- 2.40.1 → 2.40.3 无更改
- 2.40.0 03/12/23
- 2.38.1 → 2.39.5 无更改
- 2.38.0 10/02/22
- 2.36.1 → 2.37.7 无更改
- 2.36.0 04/18/22
- 2.35.1 → 2.35.8 无更改
- 2.35.0 01/24/22
- 2.33.1 → 2.34.8 无更改
- 2.33.0 08/16/21
- 2.32.1 → 2.32.7 无更改
- 2.32.0 06/06/21
- 2.31.1 → 2.31.8 无更改
- 2.31.0 03/15/21
- 2.29.1 → 2.30.9 无更改
- 2.29.0 10/19/20
- 2.28.1 无更改
- 2.28.0 07/27/20
- 2.27.1 无更改
- 2.27.0 06/01/20
- 2.25.2 → 2.26.3 无更改
- 2.25.1 02/17/20
- 2.25.0 01/13/20
- 2.24.1 → 2.24.4 无更改
- 2.24.0 11/04/19
- 2.23.1 → 2.23.4 无更改
- 2.23.0 08/16/19
- 2.22.1 → 2.22.5 无更改
- 2.22.0 06/07/19
- 2.21.1 → 2.21.4 无更改
- 2.21.0 02/24/19
- 2.20.1 → 2.20.5 无更改
- 2.20.0 12/09/18
- 2.19.1 → 2.19.6 无更改
- 2.19.0 09/10/18
- 2.18.1 → 2.18.5 无更改
- 2.18.0 06/21/18
- 2.17.1 → 2.17.6 无更改
- 2.17.0 04/02/18
- 2.15.4 → 2.16.6 无更改
- 2.14.6 12/06/19
- 2.12.5 → 2.13.7 无更改
- 2.11.4 09/22/17
- 2.10.5 09/22/17
- 2.9.5 07/30/17
- 2.8.6 07/30/17
- 2.7.6 07/30/17
- 2.6.7 05/05/17
- 2.5.6 无更改
- 2.4.12 05/05/17
- 2.2.3 → 2.3.10 无更改
- 2.1.4 12/17/14
- 2.0.5 12/17/14
概要
git fetch [<options>] [<repository> [<refspec>…]] git fetch [<options>] <group> git fetch --multiple [<options>] [(<repository> | <group>)…] git fetch --all [<options>]
描述
获取一个或多个其他存储库中的分支和/或标签(统称为“引用”),以及完成其历史记录所需的物件。远程跟踪分支将被更新(有关控制此行为的方法,请参见下面 <refspec> 的描述)。
默认情况下,指向正在获取的历史记录的任何标签也将被获取;其效果是获取指向您感兴趣的分支的标签。可以使用 --tags 或 --no-tags 选项或配置 remote.<name>.tagOpt 来更改此默认行为。通过使用显式获取标签的 refspec,您还可以获取不指向您感兴趣的分支的标签。
git fetch 可以从单个命名的存储库或 URL 获取,或者如果给出了 <group> 并且配置文件中存在 remotes.<group> 条目,则可以从多个存储库中获取。(参见 git-config[1])。
如果未指定远程存储库,则默认情况下将使用 origin
远程存储库,除非当前分支已配置上游分支。
获取的引用的名称以及它们指向的对象名称将写入 .git/FETCH_HEAD
。此信息可供脚本或其他 git 命令(如 git-pull[1])使用。
选项
- --[no-]all
-
获取所有远程存储库,除了配置变量
remote.<name>.skipFetchAll
设置的那些远程存储库。这将覆盖配置变量fetch.all
。 - -a
- --append
-
将获取的引用的引用名称和对象名称追加到
.git/FETCH_HEAD
的现有内容中。如果没有此选项,.git/FETCH_HEAD
中的旧数据将被覆盖。 - --atomic
-
使用原子事务更新本地引用。要么所有引用都更新,要么在出错时,没有引用更新。
- --depth=<depth>
-
将获取限制到每个远程分支历史记录顶部的指定数量的提交。如果获取到由
git clone
使用--depth=<depth>
选项创建的浅层存储库(参见 git-clone[1]),则将历史记录加深或缩短到指定的提交数量。不会获取加深提交的标签。 - --deepen=<depth>
-
类似于 --depth,但它指定了从当前浅层边界而不是从每个远程分支历史记录的顶部的提交数量。
- --shallow-since=<date>
-
加深或缩短浅层存储库的历史记录,以包含 <date> 之后可访问的所有提交。
- --shallow-exclude=<revision>
-
加深或缩短浅层存储库的历史记录,以排除从指定的远程分支或标签可访问的提交。此选项可以多次指定。
- --unshallow
-
如果源存储库是完整的,则将浅层存储库转换为完整存储库,删除浅层存储库施加的所有限制。
如果源存储库是浅层的,则尽可能多地获取,以便当前存储库具有与源存储库相同的历史记录。
- --update-shallow
-
默认情况下,当从浅层存储库获取时,
git fetch
会拒绝需要更新 .git/shallow 的引用。此选项更新 .git/shallow 并接受此类引用。 - --negotiation-tip=<commit|glob>
-
默认情况下,Git 会向服务器报告从所有本地引用可访问的提交,以查找常见的提交,从而尝试减小待接收的 packfile 的大小。如果指定,Git 将仅报告从给定提示可访问的提交。当用户知道哪个本地引用可能与正在获取的上游引用具有共同的提交时,这对于加快获取速度很有用。
此选项可以多次指定;如果是这样,Git 将报告从任何给定提交可访问的提交。
此选项的参数可以是引用名称上的通配符、引用或提交的(可能缩写)SHA-1。指定通配符等效于多次指定此选项,每次针对一个匹配的引用名称。
另请参见 git-config[1] 中记录的
fetch.negotiationAlgorithm
和push.negotiate
配置变量,以及下面的--negotiate-only
选项。 - --negotiate-only
-
不要从服务器获取任何内容,而是打印提供的
--negotiation-tip=*
参数的祖先,这些祖先与服务器共有。这与
--recurse-submodules=[yes|on-demand]
不兼容。在内部,它用于实现push.negotiate
选项,请参见 git-config[1]。 - --dry-run
-
显示将执行的操作,而不会进行任何更改。
- --porcelain
-
以易于脚本解析的格式将输出打印到标准输出。有关详细信息,请参见 git-fetch[1] 中的 OUTPUT 部分。
这与
--recurse-submodules=[yes|on-demand]
不兼容,并优先于fetch.output
配置选项。 - --[no-]write-fetch-head
-
将获取的远程引用的列表直接写入
$GIT_DIR
下的FETCH_HEAD
文件中。这是默认设置。从命令行传递--no-write-fetch-head
会告诉 Git 不要写入该文件。在--dry-run
选项下,该文件永远不会被写入。 - -f
- --force
-
当 git fetch 与
<src>:<dst>
refspec 一起使用时,它可能会拒绝更新本地分支,如下面<refspec>
部分所述。此选项将覆盖该检查。 - -k
- --keep
-
保留下载的包。
- --multiple
-
允许指定多个 <repository> 和 <group> 参数。不能指定任何 <refspec>。
- --[no-]auto-maintenance
- --[no-]auto-gc
-
在最后运行
git maintenance run --auto
以根据需要执行自动存储库维护。(--[no-]auto-gc
是同义词。)默认情况下启用此功能。 - --[no-]write-commit-graph
-
获取后写入提交图。这将覆盖配置设置
fetch.writeCommitGraph
。 - --prefetch
-
修改配置的 refspec 以将所有引用放置到
refs/prefetch/
命名空间中。请参阅 git-maintenance[1] 中的prefetch
任务。 - -p
- --prune
-
在获取之前,删除远程存储库中不再存在的任何远程跟踪引用。如果仅由于默认标签自动跟踪或由于 --tags 选项而获取标签,则标签不会被修剪。但是,如果由于显式 refspec(在命令行或远程配置中,例如如果远程存储库使用 --mirror 选项克隆)而获取标签,则它们也将被修剪。提供
--prune-tags
是提供标签 refspec 的简写。有关更多详细信息,请参见下面的 PRUNING 部分。
- -P
- --prune-tags
-
如果启用了
--prune
选项,则在获取之前,请移除任何不再存在于远程仓库的本地标签。与--prune
相比,此选项应更加谨慎地使用,因为它会移除任何已创建的本地引用(本地标签)。此选项是为显式标签 refspec 以及--prune
提供简写,请参阅其文档中关于此内容的讨论。有关更多详细信息,请参见下面的 PRUNING 部分。
- -n
- --no-tags
-
默认情况下,指向从远程仓库下载的对象的标签会被获取并存储在本地。此选项禁用此自动标签跟踪。远程仓库的默认行为可以通过 remote.<name>.tagOpt 设置指定。请参阅 git-config[1]。
- --refetch
-
此选项不会与服务器协商以避免传输本地已存在的提交和相关对象,而是像全新克隆一样获取所有对象。使用此选项可以重新应用配置或使用
--filter=
时的部分克隆过滤器,前提是过滤器定义已更改。自动获取后维护将执行对象数据库打包合并以移除任何重复的对象。 - --refmap=<refspec>
-
在获取命令行上列出的 refs 时,使用指定的 refspec(可以多次给出)将 refs 映射到远程跟踪分支,而不是远程仓库的
remote.*.fetch
配置变量的值。向--refmap
选项提供一个空的<refspec>
会导致 Git 忽略配置的 refspec 并完全依赖于作为命令行参数提供的 refspec。有关详细信息,请参阅“配置的远程跟踪分支”部分。 - -t
- --tags
-
除了其他将要获取的内容之外,还从远程获取所有标签(即,将远程标签
refs/tags/*
获取到具有相同名称的本地标签)。仅使用此选项不会使标签受到剪枝的影响,即使使用了 --prune 也是如此(但是,如果标签也是显式 refspec 的目标,则它们可能会被剪枝;请参阅--prune
)。 - --recurse-submodules[=(yes|on-demand|no)]
-
此选项控制是否以及在什么条件下也应获取子模块的新提交。当递归遍历子模块时,
git fetch
始终尝试获取“已更改”的子模块,即,一个子模块,其提交内容被新获取的父项目提交引用,但在本地子模块克隆中缺失。只要本地存在已更改的子模块(例如,在$GIT_DIR/modules/
中)(请参阅 gitsubmodules[7]),就可以获取它;如果上游添加了一个新的子模块,则在克隆该子模块之前无法获取它,例如通过git submodule update
。设置为on-demand时,仅获取已更改的子模块。设置为yes时,获取所有填充的子模块,以及未填充且已更改的子模块。设置为no时,从不获取子模块。
如果未指定,则使用
fetch.recurseSubmodules
的值(如果已设置)(请参阅 git-config[1]),如果未设置,则默认为on-demand。如果未使用任何值使用此选项,则默认为yes。 - -j
- --jobs=<n>
-
用于所有获取形式的并行子进程数。
如果指定了
--multiple
选项,则将并行获取不同的远程仓库。如果获取多个子模块,则将并行获取它们。要独立控制它们,请使用配置设置fetch.parallel
和submodule.fetchJobs
(请参阅 git-config[1])。通常,并行递归和多远程获取会更快。默认情况下,获取按顺序执行,而不是并行执行。
- --no-recurse-submodules
-
禁用子模块的递归获取(这与使用
--recurse-submodules=no
选项的效果相同)。 - --set-upstream
-
如果远程仓库获取成功,则添加上游(跟踪)引用,无参数的 git-pull[1]和其他命令使用该引用。有关更多信息,请参阅 git-config[1]中的
branch.<name>.merge
和branch.<name>.remote
。 - --submodule-prefix=<path>
-
在信息性消息(例如“Fetching submodule foo”)中打印的路径前添加<path>。在递归遍历子模块时,内部使用此选项。
- --recurse-submodules-default=[yes|on-demand]
-
此选项用于在内部暂时为 --recurse-submodules 选项提供一个非负的默认值。配置获取的子模块递归的所有其他方法(例如 gitmodules[5]和 git-config[1]中的设置)会覆盖此选项,直接指定 --[no-]recurse-submodules 也会覆盖此选项。
- -u
- --update-head-ok
-
默认情况下,git fetch拒绝更新对应于当前分支的 HEAD。此标志禁用该检查。这纯粹是为了git pull与git fetch进行通信的内部使用,除非您正在实现自己的 Porcelain,否则不应使用它。
- --upload-pack <upload-pack>
-
如果给出,并且要从中获取的仓库由git fetch-pack处理,则将
--exec=<upload-pack>
传递给该命令以指定在另一端运行的命令的非默认路径。 - -q
- --quiet
-
将 --quiet 传递给 git-fetch-pack 并使任何其他内部使用的 git 命令静音。进度不会报告到标准错误流。
- -v
- --verbose
-
详细输出。
- --progress
-
当标准错误流连接到终端时,默认情况下会在标准错误流上报告进度状态,除非指定了 -q。即使标准错误流未定向到终端,此标志也会强制显示进度状态。
- -o <option>
- --server-option=<option>
-
在使用协议版本 2 进行通信时,将给定的字符串传输到服务器。给定的字符串不得包含 NUL 或 LF 字符。服务器对服务器选项(包括未知选项)的处理是特定于服务器的。当给出多个
--server-option=<option>
时,它们都将按命令行上列出的顺序发送到另一端。 - --show-forced-updates
-
默认情况下,git 检查在获取过程中分支是否被强制更新。这可以通过 fetch.showForcedUpdates 禁用,但 --show-forced-updates 选项保证此检查会发生。请参阅 git-config[1]。
- --no-show-forced-updates
-
默认情况下,git 检查在获取过程中分支是否被强制更新。传递 --no-show-forced-updates 或将 fetch.showForcedUpdates 设置为 false 以出于性能原因跳过此检查。如果在git-pull期间使用,则 --ff-only 选项仍将在尝试快速转发更新之前检查强制更新。请参阅 git-config[1]。
- -4
- --ipv4
-
仅使用 IPv4 地址,忽略 IPv6 地址。
- -6
- --ipv6
-
仅使用 IPv6 地址,忽略 IPv4 地址。
- <repository>
-
“远程”仓库,它是获取或拉取操作的来源。此参数可以是 URL(请参阅下面的 GIT URLS 部分)或远程仓库的名称(请参阅下面的 REMOTES 部分)。
- <group>
-
一个名称,引用配置文件中 remotes.<group> 的值作为一系列仓库。(请参阅 git-config[1])。
- <refspec>
-
指定要获取哪些 refs 以及要更新哪些本地 refs。当命令行上没有出现任何 <refspec> 时,将从
remote.<repository>.fetch
变量中读取要获取的 refs(请参阅下面的 CONFIGURED REMOTE-TRACKING BRANCHES)。<refspec> 参数的格式是可选的加号
+
,后跟源<src>,后跟冒号:
,后跟目标 ref <dst>。当<dst>为空时,可以省略冒号。<src> 通常是 ref,但也可以是完整拼写的十六进制对象名称。<refspec> 可以在其 <src> 中包含一个
*
,以指示简单的模式匹配。这样的 refspec 就像一个 glob,匹配任何具有相同前缀的 ref。模式 <refspec> 必须在 <src> 和 <dst> 中都有一个*
。它将通过用从源匹配的内容替换*
来将 refs 映射到目标。如果 refspec 以
^
为前缀,则它将被解释为负 refspec。此类 refspec 不会指定要获取哪些 refs 或要更新哪些本地 refs,而是指定要排除的 refs。如果 ref 至少匹配一个正 refspec,并且不匹配任何负 refspec,则它将被视为匹配。负 refspec 可用于限制模式 refspec 的范围,使其不包含特定的 refs。负 refspec 本身可以是模式 refspec。但是,它们只能包含 <src>,并且不指定 <dst>。完整拼写的十六进制对象名称也不受支持。tag <tag>
与refs/tags/<tag>:refs/tags/<tag>
的含义相同;它请求获取到指定标签为止的所有内容。匹配 <src> 的远程引用会被获取,如果 <dst> 不是空字符串,则会尝试更新匹配它的本地引用。
是否允许在不使用
--force
的情况下进行更新,取决于它被获取到的引用命名空间、被获取的对象类型以及更新是否被认为是快进更新。通常,获取时的规则与推送时相同,有关这些规则的详细信息,请参阅 git-push[1] 中的<refspec>...
部分。下面将说明 git fetch 特有的规则例外情况。在 Git 2.20 版本之前,与使用 git-push[1] 推送时不同,对
refs/tags/*
的任何更新都将在 refspec 中没有+
(或--force
)的情况下被接受。在获取时,我们会随意地将来自远程的所有标签更新视为强制获取。从 Git 2.20 版本开始,获取以更新refs/tags/*
的方式与推送时相同。即,在 refspec 中没有+
(或--force
)的情况下,任何更新都将被拒绝。与使用 git-push[1] 推送时不同,对
refs/{tags,heads}/*
之外的任何更新都将在 refspec 中没有+
(或--force
)的情况下被接受,无论这是否是交换例如树对象为 Blob 对象,或将一个提交替换为另一个提交,而该提交不是前一个提交的祖先等。与使用 git-push[1] 推送时不同,没有任何配置可以修改这些规则,也没有类似于
pre-receive
钩子的pre-fetch
钩子。与使用 git-push[1] 推送时一样,上述关于不允许更新内容的所有规则都可以通过在 refspec 前面添加可选的前导
+
(或使用--force
命令行选项)来覆盖。唯一的例外是,无论如何强制,refs/heads/*
命名空间都不会接受非提交对象。注意当您要获取的远程分支已知会定期回退和重新设置基准时,预计其新的顶端不会是其先前顶端的后代(如上次您获取时存储在您的远程跟踪分支中)。您需要使用 +
符号来指示此类分支需要非快进更新。无法确定或声明一个分支是否会以这种行为在存储库中可用;拉取用户只需要知道这是该分支的预期使用模式。 - --stdin
-
除了作为参数提供的 refspec 之外,还从 stdin 读取每行一个 refspec。不支持“tag <name>”格式。
Git URL
通常,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/
这两种语法基本等效,但在克隆时除外,前者表示 --local
选项。有关详细信息,请参阅 git-clone[1]。
git clone
、git fetch
和 git 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。
远程
以下名称之一可以用作 <repository>
参数的替代
-
Git 配置文件中的远程:
$GIT_DIR/config
、 -
$GIT_DIR/remotes
目录中的文件,或 -
$GIT_DIR/branches
目录中的文件。
所有这些都允许您省略命令行中的 refspec,因为它们都包含一个 refspec,git 会默认使用它。
配置文件中的命名远程
您可以选择提供之前使用 git-remote[1]、git-config[1] 或甚至手动编辑 $GIT_DIR/config
文件配置的远程的名称。此远程的 URL 将用于访问存储库。此远程的 refspec 将在您未在命令行上提供 refspec 时默认使用。配置文件中的条目将如下所示
[remote "<name>"] url = <URL> pushurl = <pushurl> push = <refspec> fetch = <refspec>
<pushurl>
仅用于推送。它是可选的,默认为 <URL>
。推送到远程会影响所有定义的 pushurl 或如果未定义 pushurl 则影响所有定义的 url。但是,如果定义了多个 url,则获取只会从第一个定义的 url 获取。
$GIT_DIR/remotes
中的命名文件
您可以选择提供 $GIT_DIR/remotes
中的文件的名称。此文件中的 URL 将用于访问存储库。此文件中的 refspec 将在您未在命令行上提供 refspec 时用作默认值。此文件应具有以下格式
URL: one of the above URL formats Push: <refspec> Pull: <refspec>
Push:
行由 git push 使用,Pull:
行由 git pull 和 git fetch 使用。可以为其他分支映射指定多个 Push:
和 Pull:
行。
$GIT_DIR/branches
中的命名文件
您可以选择提供 $GIT_DIR/branches
中的文件的名称。此文件中的 URL 将用于访问存储库。此文件应具有以下格式
<URL>#<head>
<URL>
是必需的;#<head>
是可选的。
根据操作的不同,如果未在命令行上提供 refspec,git 将使用以下 refspec 之一。<branch>
是 $GIT_DIR/branches
中此文件的名称,<head>
默认为 master
。
git fetch 使用
refs/heads/<head>:refs/heads/<branch>
git push 使用
HEAD:refs/heads/<head>
配置的远程跟踪分支
您经常通过定期重复地从同一个远程存储库获取数据来与之交互。为了跟踪此类远程存储库的进度,git fetch
允许您配置 remote.<repository>.fetch
配置变量。
通常,此类变量可能如下所示
[remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/*
此配置以两种方式使用
-
当
git fetch
在不指定命令行上要获取的分支和/或标签的情况下运行时,例如git fetch origin
或git fetch
,remote.<repository>.fetch
值用作 refspec——它们指定要获取哪些引用以及要更新哪些本地引用。上面的示例将获取origin
中存在的所有分支(即与值左侧匹配的任何引用refs/heads/*
),并在refs/remotes/origin/*
层次结构中更新相应的远程跟踪分支。 -
当
git fetch
在命令行上运行并带有要获取的显式分支和/或标签时,例如git fetch origin master
,命令行上给出的 <refspec> 确定要获取的内容(例如,示例中的master
,它是master:
的简写,它又表示“获取 master 分支,但我没有在命令行中明确说明要使用哪个远程跟踪分支来更新它”),并且示例命令将仅获取 master 分支。remote.<repository>.fetch
值确定更新哪个远程跟踪分支(如果有)。当以这种方式使用时,remote.<repository>.fetch
值对决定 获取 的内容没有任何影响(即,当命令行列出 refspec 时,这些值不用作 refspec);它们仅用于决定通过充当映射来存储获取的引用的 位置。
可以通过在命令行上给出 --refmap=<refspec>
参数来覆盖 remote.<repository>.fetch
值的后一种用法。
修剪
Git 默认情况下会保留数据,除非它被显式丢弃;这扩展到保留对远程分支的本地引用,而这些分支本身已删除了这些分支。
如果任其累积,这些陈旧的引用可能会导致大型且繁忙的存储库(这些存储库有很多分支变更)的性能下降,例如,使 git branch -a --contains <commit>
等命令的输出变得不必要地冗长,以及影响任何其他将使用已知引用完整集的操作。
可以使用以下任一方法一次性删除这些远程跟踪引用
# While fetching $ git fetch --prune <name> # Only prune, don't fetch $ git remote prune <name>
要将修剪引用作为您正常工作流程的一部分,而无需记住运行该操作,请在全局范围内设置 fetch.prune
,或在配置中为每个远程设置 remote.<name>.prune
。请参阅 git-config[1]。
这里事情变得棘手且更具体。修剪功能实际上并不关心分支,而是将本地 ←→ 远程引用作为远程的 refspec 的函数进行修剪(请参阅 <refspec>
和上面 配置的远程跟踪分支)。
因此,如果远程的 refspec 包含例如 refs/tags/*:refs/tags/*
,或者您手动运行例如 git fetch --prune <name> "refs/tags/*:refs/tags/*"
,则删除的不是陈旧的远程跟踪分支,而是远程上不存在的任何本地标签。
这可能与您的预期不符,即您希望修剪远程 <name>
,但也明确地从中获取标签,因此当您从中获取时,会删除所有本地标签,其中大多数可能并非来自 <name>
远程。
因此,在与像refs/tags/*:refs/tags/*
这样的 refspec 或任何可能将来自多个远程仓库的引用映射到相同本地命名空间的其他 refspec 一起使用时,请小心。
由于保持远程仓库上的分支和标签最新是一个常见的用例,因此可以与--prune
一起提供--prune-tags
选项来修剪远程仓库上不存在的本地标签,并强制更新不同的标签。标签修剪也可以在配置中使用fetch.pruneTags
或remote.<name>.pruneTags
启用。请参阅git-config[1]。
--prune-tags
选项等同于在远程仓库的 refspec 中声明refs/tags/*:refs/tags/*
。这可能导致一些看似奇怪的交互。
# These both fetch tags $ git fetch --no-tags origin 'refs/tags/*:refs/tags/*' $ git fetch --no-tags --prune-tags origin
在没有--prune
或其配置版本的情况下提供时,它不会出错的原因是为了配置版本的灵活性,并保持命令行标志的功能与配置版本的功能之间的 1=1 映射。
例如,在~/.gitconfig
中配置fetch.pruneTags=true
以便在运行git fetch --prune
时修剪标签是合理的,而无需使每次不带--prune
的git fetch
调用都出错。
使用--prune-tags
修剪标签在获取 URL 而不是命名远程仓库时也有效。所有这些都将修剪在 origin 上找不到的标签。
$ git fetch origin --prune --prune-tags $ git fetch origin --prune 'refs/tags/*:refs/tags/*' $ git fetch <url-of-origin> --prune --prune-tags $ git fetch <url-of-origin> --prune 'refs/tags/*:refs/tags/*'
输出
"git fetch"的输出取决于使用的传输方法;本节描述通过 Git 协议(本地或通过 ssh)和智能 HTTP 协议获取时的输出。
获取的状态以表格形式输出,每一行代表单个引用的状态。每一行都具有以下形式
<flag> <summary> <from> -> <to> [<reason>]
使用--porcelain
时,输出格式旨在机器可解析。与人类可读的输出格式相比,它因此打印到标准输出而不是标准错误。每一行都具有以下形式
<flag> <old-object-id> <new-object-id> <local-reference>
仅当使用 --verbose 选项时,才会显示最新引用的状态。
在紧凑输出模式下,由配置变量 fetch.output 指定,如果在另一个字符串中找到整个<from>
或<to>
,则它将在另一个字符串中替换为*
。例如,master -> origin/master
变为master -> origin/*
。
示例
-
更新远程跟踪分支
$ git fetch origin
上述命令将远程
refs/heads/
命名空间中的所有分支复制并存储到本地refs/remotes/origin/
命名空间中,除非使用remote.<repository>.fetch
选项指定非默认 refspec。 -
显式使用 refspec
$ git fetch origin +seen:seen maint:tmp
这将更新(或根据需要创建)本地存储库中的分支
seen
和tmp
,方法是从远程存储库中的分支(分别)seen
和maint
获取。即使
seen
分支没有快进,它也会被更新,因为它以加号作为前缀;tmp
不会。 -
查看远程仓库的分支,无需在本地存储库中配置远程仓库
$ git fetch git://git.kernel.org/pub/scm/git/git.git maint $ git log FETCH_HEAD
第一个命令从
git://git.kernel.org/pub/scm/git/git.git
处的存储库中获取maint
分支,第二个命令使用FETCH_HEAD
与git-log[1]一起检查该分支。获取的对象最终将被 git 的内置管家删除(请参阅git-gc[1])。
安全
获取和推送协议并非旨在防止一方从另一存储库中窃取不打算共享的数据。如果您有需要保护免受恶意对等体攻击的私有数据,最好的选择是将其存储在另一个存储库中。这适用于客户端和服务器。特别是,服务器上的命名空间对于读取访问控制无效;您应该仅向您信任读取整个存储库访问权限的客户端授予命名空间的读取访问权限。
已知的攻击媒介如下
-
受害者发送“have”行,宣传其拥有的对象的 ID,这些对象并非明确打算共享,但如果对等体也拥有这些对象,则可用于优化传输。攻击者选择要窃取的对象 ID X 并发送对 X 的引用,但无需发送 X 的内容,因为受害者已经拥有它。现在受害者相信攻击者拥有 X,并且它稍后将 X 的内容发送回攻击者。(这种攻击对于客户端在服务器上执行最简单,方法是在客户端有权访问的命名空间中创建对 X 的引用,然后获取它。服务器对客户端执行此操作的最可能方法是“合并”X 到公共分支中,并希望用户在此分支上进行其他工作并将其推回服务器,而没有注意到合并。)
-
与 #1 一样,攻击者选择要窃取的对象 ID X。受害者发送攻击者已经拥有的对象 Y,攻击者错误地声称拥有 X 而没有 Y,因此受害者发送 Y 作为针对 X 的增量。增量向攻击者揭示了 X 中与 Y 相似的区域。
配置
本节中此行以下的所有内容都是从git-config[1]文档中选择性地包含的。内容与那里找到的内容相同。
- fetch.recurseSubmodules
-
此选项控制
git fetch
(以及git pull
中的底层 fetch)是否会递归地获取到已填充的子模块中。此选项可以设置为布尔值或设置为按需。将其设置为布尔值会更改 fetch 和 pull 的行为,以便在设置为 true 时无条件地递归到子模块中,或者在设置为 false 时根本不递归。当设置为按需时,fetch 和 pull 仅当其超级项目检索更新子模块引用的提交时才会递归到已填充的子模块中。默认为按需,或在设置时默认为submodule.recurse的值。 - fetch.fsckObjects
-
如果将其设置为 true,则 git-fetch-pack 将检查所有获取的对象。有关检查的内容,请参阅
transfer.fsckObjects
。默认为 false。如果未设置,则使用transfer.fsckObjects
的值。 - fetch.fsck.<msg-id>
-
类似于
fsck.<msg-id>
,但由git-fetch-pack[1]而不是git-fsck[1]使用。有关详细信息,请参阅fsck.<msg-id>
文档。 - fetch.fsck.skipList
-
类似于
fsck.skipList
,但由git-fetch-pack[1]而不是git-fsck[1]使用。有关详细信息,请参阅fsck.skipList
文档。 - fetch.unpackLimit
-
如果通过 Git 本机传输获取的对象数量低于此限制,则这些对象将解包到松散的对象文件中。但是,如果接收到的对象数量等于或超过此限制,则接收到的包将在添加任何缺少的增量基数后作为包存储。存储来自推送的包可以使推送操作更快地完成,尤其是在速度较慢的文件系统上。如果未设置,则使用
transfer.unpackLimit
的值。 - fetch.prune
-
如果为 true,则 fetch 将自动表现得好像在命令行上提供了
--prune
选项。另请参阅remote.<name>.prune
和git-fetch[1]的修剪部分。 - fetch.pruneTags
-
如果为 true,则 fetch 将自动表现得好像在修剪时提供了
refs/tags/*:refs/tags/*
refspec,如果尚未设置。这允许设置此选项和fetch.prune
以保持与上游引用的 1=1 映射。另请参阅remote.<name>.pruneTags
和git-fetch[1]的修剪部分。 - fetch.all
-
如果为 true,则 fetch 将尝试更新所有可用的远程仓库。此行为可以通过传递
--no-all
或显式指定要从中获取的一个或多个远程仓库来覆盖。默认为 false。 - fetch.output
-
控制如何打印引用更新状态。有效值为
full
和compact
。默认值为full
。有关详细信息,请参阅git-fetch[1]中的输出部分。 - fetch.negotiationAlgorithm
-
控制在协商服务器要发送的包文件内容时如何发送有关本地存储库中提交的信息。设置为“consecutive”以使用一种算法,该算法遍历连续的提交并检查每个提交。设置为“skipping”以使用一种算法,该算法跳过提交以加快收敛速度,但这可能导致包文件大于必要;或设置为“noop”以根本不发送任何信息,这几乎肯定会导致包文件大于必要,但会跳过协商步骤。设置为“default”以覆盖先前设置并使用默认行为。默认值通常为“consecutive”,但如果
feature.experimental
为 true,则默认值为“skipping”。未知值会导致git fetch出错。另请参阅git-fetch[1]的
--negotiate-only
和--negotiation-tip
选项。 - fetch.showForcedUpdates
-
设置为 false 以在git-fetch[1]和git-pull[1]命令中启用
--no-show-forced-updates
。默认为 true。 - fetch.parallel
-
指定一次并行运行的最大获取操作数(子模块,或在git-fetch[1]的
--multiple
选项生效时为远程仓库)。值为 0 将提供一些合理的默认值。如果未设置,则默认为 1。
对于子模块,可以使用
submodule.fetchJobs
配置设置覆盖此设置。 - fetch.writeCommitGraph
-
设置为 true 以在每次下载远程包文件的
git fetch
命令后写入提交图。使用--split
选项,大多数执行将在现有提交图文件的基础上创建一个非常小的提交图文件。偶尔,这些文件会合并,写入可能需要更长时间。拥有更新的提交图文件有助于提高许多 Git 命令的性能,包括git merge-base
、git push -f
和git log --graph
。默认为 false。 - fetch.bundleURI
-
此值存储一个 URI,用于在从原始 Git 服务器执行增量获取之前从捆绑包 URI 下载 Git 对象数据。这类似于 git-clone[1] 中
--bundle-uri
选项的行为。如果提供的捆绑包 URI 包含为增量获取组织的捆绑包列表,则git clone --bundle-uri
将设置fetch.bundleURI
值。如果修改此值并且存储库具有
fetch.bundleCreationToken
值,则在从新的捆绑包 URI 获取之前删除该fetch.bundleCreationToken
值。 - fetch.bundleCreationToken
-
当使用
fetch.bundleURI
从使用“creationToken”启发式的捆绑包列表增量获取时,此配置值存储已下载捆绑包的最大creationToken
值。如果广告的creationToken
不严格大于此值,则此值用于防止将来下载捆绑包。creation token 值由提供特定捆绑包 URI 的提供者选择。如果修改
fetch.bundleURI
处的 URI,则在获取之前确保删除fetch.bundleCreationToken
值的值。
错误
使用 --recurse-submodules 只能获取本地存在的子模块(例如 $GIT_DIR/modules/
中)中的新提交。如果上游添加了新的子模块,则在克隆该子模块(例如通过 git submodule update
)之前无法获取该子模块。预计将在未来的 Git 版本中修复此问题。
Git
是 git[1] 套件的一部分