设置和配置
获取和创建项目
基本快照
分支和合并
共享和更新项目
检查和比较
补丁
调试
邮件
外部系统
服务器管理
指南
管理
底层命令
- 2.48.1 → 2.49.0 无更改
-
2.48.0
2025-01-10
- 2.47.2 无更改
-
2.47.1
2024-11-25
- 2.46.3 → 2.47.0 无更改
-
2.46.2
2024-09-23
- 2.45.1 → 2.46.1 无更改
-
2.45.0
2024-04-29
- 2.44.1 → 2.44.3 无更改
-
2.44.0
2024-02-23
- 2.43.1 → 2.43.6 无更改
-
2.43.0
2023-11-20
- 2.42.1 → 2.42.4 无更改
-
2.42.0
2023-08-21
- 2.41.1 → 2.41.3 无更改
-
2.41.0
2023-06-01
- 2.40.1 → 2.40.4 无更改
-
2.40.0
2023-03-12
- 2.38.1 → 2.39.5 无更改
-
2.38.0
2022-10-02
- 2.36.1 → 2.37.7 无更改
-
2.36.0
2022-04-18
- 2.35.1 → 2.35.8 无更改
-
2.35.0
2022-01-24
- 2.33.1 → 2.34.8 无更改
-
2.33.0
2021-08-16
- 2.32.1 → 2.32.7 无更改
-
2.32.0
2021-06-06
- 2.31.1 → 2.31.8 无更改
-
2.31.0
2021-03-15
- 2.29.1 → 2.30.9 无更改
-
2.29.0
2020-10-19
- 2.28.1 无更改
-
2.28.0
2020-07-27
- 2.27.1 无更改
-
2.27.0
2020-06-01
- 2.25.2 → 2.26.3 无更改
-
2.25.1
2020-02-17
-
2.25.0
2020-01-13
- 2.24.1 → 2.24.4 无更改
-
2.24.0
2019-11-04
- 2.23.1 → 2.23.4 无更改
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 无更改
-
2.22.0
2019-06-07
- 2.21.1 → 2.21.4 无更改
-
2.21.0
2019-02-24
- 2.20.1 → 2.20.5 无更改
-
2.20.0
2018-12-09
- 2.19.1 → 2.19.6 无更改
-
2.19.0
2018-09-10
- 2.18.1 → 2.18.5 无更改
-
2.18.0
2018-06-21
- 2.17.1 → 2.17.6 无更改
-
2.17.0
2018-04-02
- 2.15.4 → 2.16.6 无更改
-
2.14.6
2019-12-06
- 2.12.5 → 2.13.7 无更改
-
2.11.4
2017-09-22
-
2.10.5
2017-09-22
-
2.9.5
2017-07-30
-
2.8.6
2017-07-30
-
2.7.6
2017-07-30
-
2.6.7
2017-05-05
- 2.5.6 无更改
-
2.4.12
2017-05-05
- 2.2.3 → 2.3.10 无更改
-
2.1.4
2014-12-17
-
2.0.5
2014-12-17
概要
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 更改此默认行为。通过使用显式抓取标签的引用规范,你可以抓取未指向你感兴趣的分支的标签。
如果给定了 <group> 并且配置文件中存在 remotes.<group> 条目,git fetch 可以从单个命名仓库或 URL 抓取,也可以一次从多个仓库抓取。(参见 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=<ref>
-
加深或缩短浅仓库的历史记录,以排除从指定的远程分支或标签可访问的提交。 可以多次指定此选项。
- --unshallow
-
如果源仓库是完整的,则将浅仓库转换为完整仓库,删除浅仓库施加的所有限制。
如果源仓库是浅的,则尽可能多地抓取,以便当前仓库具有与源仓库相同的历史记录。
- --update-shallow
-
默认情况下,从浅仓库抓取时,
git fetch
拒绝需要更新 .git/shallow 的引用。 此选项更新 .git/shallow 并接受此类引用。 - --negotiation-tip=<commit|glob>
-
默认情况下,Git 会向服务器报告从所有本地引用可访问的提交,以查找公共提交,从而尝试减小要接收的包文件的大小。 如果指定,Git 将仅报告从给定提示可访问的提交。 当用户知道哪个本地引用可能与要抓取的上游引用有公共提交时,这对于加快抓取速度很有用。
可以多次指定此选项; 如果是这样,Git 将报告从任何给定提交可访问的提交。
此选项的参数可以是引用名称上的 glob,一个引用,或提交的(可能缩写的)SHA-1。 指定 glob 相当于多次指定此选项,每个匹配的引用名称一次。
另请参阅 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
config 选项。 - --[no-]write-fetch-head
-
将抓取的远程引用列表直接写入
$GIT_DIR
下的FETCH_HEAD
文件。 这是默认设置。 从命令行传递--no-write-fetch-head
会告诉 Git 不要写入该文件。 在--dry-run
选项下,永远不会写入该文件。 - -f
- --force
-
当 git fetch 与
<src>:<dst>
引用规范一起使用时,它可能会拒绝更新本地分支,如下面的<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
-
修改配置的引用规范,以将所有引用放入
refs/prefetch/
命名空间中。 请参阅 git-maintenance[1] 中的prefetch
任务。 - -p
- --prune
-
在抓取之前,删除远程仓库上不再存在的任何远程跟踪引用。 如果仅由于默认标签自动跟随或由于 --tags 选项而抓取标签,则标签不受修剪的约束。 但是,如果由于显式引用规范而抓取标签(无论是在命令行上还是在远程配置中,例如,如果使用 --mirror 选项克隆了远程仓库),则它们也受修剪的约束。 提供
--prune-tags
是提供标签引用规范的简写形式。有关更多详细信息,请参见下面的 PRUNING 部分。
- -P
- --prune-tags
-
如果启用了
--prune
,则在抓取之前,删除远程仓库上不再存在的任何本地标签。 应该更小心地使用此选项,与--prune
不同,它将删除已创建的任何本地引用(本地标签)。 此选项是提供显式标签引用规范以及--prune
的简写形式,请参见其文档中的讨论。有关更多详细信息,请参见下面的 PRUNING 部分。
- -n
- --no-tags
-
默认情况下,会获取并本地存储指向从远程仓库下载的对象的标签。此选项禁用此自动标签跟踪。可以使用
remote.<name>.tagOpt
设置来指定远程仓库的默认行为。请参阅 git-config[1]。 - --refetch
-
此选项会像全新克隆一样获取所有对象,而不是与服务器协商以避免传输本地已存在的提交和关联对象。当配置中的部分克隆过滤器或使用
--filter=
的过滤器定义已更改时,请使用此选项重新应用。自动的获取后维护将执行对象数据库打包合并,以删除任何重复对象。 - --refmap=<refspec>
-
当获取命令行上列出的引用时,使用指定的引用规范(可以多次给出)将引用映射到远程跟踪分支,而不是远程仓库的
remote.*.fetch
配置变量的值。为--refmap
选项提供一个空的<refspec>
会导致 Git 忽略配置的引用规范,而完全依赖于作为命令行参数提供的引用规范。有关详细信息,请参阅“配置的远程跟踪分支”部分。 - -t
- --tags
-
从远程仓库获取所有标签(即,将远程标签
refs/tags/*
获取到具有相同名称的本地标签),以及其他通常会被获取的内容。单独使用此选项不会导致标签被修剪,即使使用了 --prune 也是如此(尽管如果标签也是显式引用规范的目标,则可能会被修剪;请参阅--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>
-
将 <path> 添加到信息性消息中打印的路径之前,例如“Fetching submodule foo”。当递归遍历子模块时,此选项在内部使用。
- --recurse-submodules-default=[yes|on-demand]
-
此选项在内部用于临时为 --recurse-submodules 选项提供一个非负默认值。配置 fetch 的子模块递归的所有其他方法(例如 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>
时,它们会按照命令行上列出的顺序发送到另一端。当命令行上没有给出--server-option=<option>
时,则使用配置变量remote.<name>.serverOption
的值。 - --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>
-
指定要获取哪些引用以及要更新哪些本地引用。当命令行上没有出现 <refspec> 时,要获取的引用将从
remote.<repository>.fetch
变量中读取(请参阅下面的 配置的远程跟踪分支)。<refspec> 参数的格式是一个可选的加号
+
,后跟源 <src>,后跟一个冒号:
,后跟目标 <dst>。当 <dst> 为空时,可以省略冒号。 <src> 通常是一个引用,或是一个带有单个*
的 glob 模式,用于匹配一组引用,但它也可以是一个完全拼写的十六进制对象名称。<refspec> 可以在其 <src> 中包含一个
*
,以指示一个简单的模式匹配。这样的引用规范的作用类似于一个 glob,它可以匹配任何带有该模式的引用。模式 <refspec> 必须在 <src> 和 <dst> 中都有一个且只有一个*
。它将通过将*
替换为从源匹配的内容,将引用映射到目标。如果一个引用规范以
^
为前缀,它将被解释为负引用规范。这样的引用规范不是指定要获取哪些引用或要更新哪些本地引用,而是指定要排除的引用。如果一个引用至少匹配一个正引用规范,并且不匹配任何负引用规范,则认为该引用匹配。负引用规范对于限制模式引用规范的范围非常有用,这样它就不会包含特定的引用。负引用规范本身可以是模式引用规范。但是,它们只能包含 <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/*
的任何更新都将被接受,而无需在引用规范中使用+
(或--force
)。在获取时,我们随意地认为来自远程仓库的所有标签更新都是强制获取。自 Git 版本 2.20 以来,获取以更新refs/tags/*
的工作方式与推送时相同。也就是说,如果没有在引用规范中使用+
(或--force
),任何更新都将被拒绝。与使用 git-push[1] 进行推送不同,对
refs/{tags,heads}/*
之外的任何更新都将被接受,而无需在引用规范中使用+
(或--force
),无论是交换树对象和 blob,还是交换提交和另一个没有前一个提交作为祖先的提交等。与使用 git-push[1] 进行推送不同,没有任何配置可以修改这些规则,也没有类似于
pre-receive
钩子的pre-fetch
钩子。与使用 git-push[1] 进行推送类似,上述关于不允许作为更新的所有规则都可以通过在 refspec 前面添加可选的
+
符号(或使用--force
命令行选项)来覆盖。唯一的例外是,无论如何强制,refs/heads/*
命名空间都不会接受非 commit 对象。注意当您想要拉取的远程分支已知会被定期回退和 rebase 时,其新的顶端(tip)将不会是其之前的顶端(上次拉取时存储在您的远程跟踪分支中的顶端)的后代。您应该使用 +
符号来表示此类分支需要非快进更新。没有办法确定或声明分支将以这种行为在存储库中提供;拉取用户只需知道这是分支的预期使用模式。 - --stdin
-
除了作为参数提供的 refspec 外,还从 stdin 读取 refspec,每行一个。"tag <name>" 格式不受支持。
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>
另一种类似 scp 的语法也可以与 ssh 协议一起使用
-
[<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-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。
REMOTES
以下名称之一可以代替 URL 用作 <repository>
参数
-
Git 配置文件中的 remote:
$GIT_DIR/config
, -
$GIT_DIR/remotes
目录中的文件,或 -
$GIT_DIR/branches
目录中的文件。
所有这些还允许您从命令行省略 refspec,因为它们每个都包含一个 git 默认使用的 refspec。
配置文件中的命名 remote
您可以选择提供先前使用 git-remote[1]、git-config[1] 甚至通过手动编辑 $GIT_DIR/config
文件配置的 remote 的名称。此 remote 的 URL 将用于访问存储库。当您在命令行上未提供 refspec 时,将默认使用此 remote 的 refspec。配置文件中的条目如下所示
[remote "<name>"] url = <URL> pushurl = <pushurl> push = <refspec> fetch = <refspec>
<pushurl>
仅用于推送。它是可选的,默认为 <URL>
。推送到 remote 会影响所有定义的 pushurl 或所有定义的 url(如果未定义 pushurl)。但是,拉取只会从第一个定义的 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);它们仅用于通过充当映射来决定 *哪些* 被拉取的引用被存储在哪里。
remote.<repository>.fetch
值的后一种用法可以通过在命令行上给出 --refmap=<refspec>
参数来覆盖。
PRUNING
Git 的默认处置是保留数据,除非明确丢弃它;这扩展到保留对远程分支的本地引用,即使远程本身已删除这些分支。
如果任其积累,这些过时的引用可能会降低大型繁忙存储库的性能,这些存储库有很多分支更迭,例如,使像 git branch -a --contains <commit>
这样的命令的输出变得不必要地冗长,以及影响任何其他将与已知引用的完整集合一起工作的东西。
这些远程跟踪引用可以使用以下两种方法之一来一次性删除:
# While fetching $ git fetch --prune <name> # Only prune, don't fetch $ git remote prune <name>
要修剪引用作为正常工作流程的一部分,而无需记住运行该命令,请在配置中全局设置 fetch.prune
,或每个 remote 设置 remote.<name>.prune
。请参阅 git-config[1]。
以下是事情变得棘手和更具体的地方。修剪功能实际上并不关心分支,而是将本地 ←→ 远程引用作为 remote 的 refspec 的函数进行修剪(请参阅上面的 <refspec>
和 配置的远程跟踪分支)。
因此,如果 remote 的 refspec 包括例如 refs/tags/*:refs/tags/*
,或者您手动运行例如 git fetch --prune <name> "refs/tags/*:refs/tags/*"
,则不会删除过时的远程跟踪分支,而是删除远程上不存在的任何本地标签。
这可能不是您所期望的,即您想要修剪远程 <name>
,但也明确地从中拉取标签,因此当您从中拉取时,您会删除所有本地标签,其中大多数可能一开始就不是来自 <name>
远程的。
因此,当将其与像 refs/tags/*:refs/tags/*
这样的 refspec,或任何其他可能将来自多个 remote 的引用映射到同一本地命名空间的 refspec 一起使用时,请务必小心。
由于保持与远程上的分支和标签同步是一个常见的用例,因此 --prune-tags
选项可以与 --prune
一起提供,以修剪远程上不存在的本地标签,并强制更新那些不同的标签。也可以在配置中使用 fetch.pruneTags
或 remote.<name>.pruneTags
来启用标签修剪。请参阅 git-config[1]。
--prune-tags
选项等效于在 remote 的 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
调用都报错。
当从 URL(而不是指定的远程仓库)获取时,使用 --prune-tags
删除标签也有效。 这些操作都会删除在 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)和 Smart HTTP 协议进行获取时的输出。
获取的状态以表格形式输出,每一行代表一个 ref 的状态。每一行的格式如下:
<flag> <summary> <from> -> <to> [<reason>]
当使用 --porcelain
时,输出格式旨在可被机器解析。 与人类可读的输出格式相反,它会打印到标准输出而不是标准错误。 每一行的格式如下:
<flag> <old-object-id> <new-object-id> <local-reference>
只有在使用 --verbose 选项时,才会显示最新 ref 的状态。
在紧凑输出模式(通过配置变量 fetch.output 指定)下,如果在另一个字符串中找到完整的 <from>
或 <to>
,则它将被替换为另一个字符串中的 *
。例如,master -> origin/master
变为 master -> origin/*
。
示例
-
更新远程跟踪分支
$ git fetch origin
除非使用
remote.<repository>.fetch
选项指定非默认的 refspec,否则以上命令会将所有分支从远程refs/heads/
命名空间复制到本地refs/remotes/origin/
命名空间。 -
显式使用 refspecs
$ git fetch origin +seen:seen maint:tmp
这会通过从远程存储库中的
seen
和maint
分支(分别)获取来更新(或根据需要创建)本地存储库中的seen
和tmp
分支。即使
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])。
安全性
fetch 和 push 协议并非旨在防止一方从另一方窃取不打算共享的数据。 如果您有需要保护免受恶意对等方侵害的私有数据,最好的选择是将其存储在另一个存储库中。 这适用于客户端和服务器。 特别是,服务器上的命名空间对于读取访问控制无效; 您应该仅授予对命名空间的读取访问权限,授予您信任其具有对整个存储库的读取访问权限的客户端。
已知的攻击向量如下:
-
受害者发送“have”行,以声明其拥有的对象的 ID,这些对象并非明确打算共享,但如果对等方也拥有它们,则可用于优化传输。 攻击者选择要窃取的对象 ID X 并将 ref 发送到 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)是否会递归地获取到已填充的子模块中。 可以将此选项设置为布尔值或 *on-demand*。 如果将其设置为布尔值,则当设置为 true 时,fetch 和 pull 的行为会无条件地递归到子模块中,而当设置为 false 时,则根本不会递归。 当设置为 *on-demand* 时,只有当其超级项目检索到更新子模块引用的提交时,fetch 和 pull 才会递归到已填充的子模块中。 默认为 *on-demand*,如果设置了 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] 的 PRUNING 部分。 - fetch.pruneTags
-
如果为 true,则在删除时,如果尚未设置,fetch 将自动表现得好像提供了
refs/tags/*:refs/tags/*
refspec。 这样可以同时设置此选项和fetch.prune
,以保持与上游 ref 的 1=1 映射。 另请参见remote.<name>.pruneTags
和 git-fetch[1] 的 PRUNING 部分。 - fetch.all
-
如果为 true,则 fetch 将尝试更新所有可用的远程仓库。 可以通过传递
--no-all
或显式指定一个或多个要从中获取的远程仓库来覆盖此行为。 默认为 false。 - fetch.output
-
控制 ref 更新状态的打印方式。 有效值为
full
和compact
。 默认值为full
。 有关详细信息,请参见 git-fetch[1] 中的 OUTPUT 部分。 - 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,以便在每次从远程下载 pack-file 的
git fetch
命令后写入 commit-graph。 使用--split
选项,大多数执行会在现有 commit-graph 文件之上创建一个非常小的 commit-graph 文件。 有时,这些文件会合并,写入可能需要更长时间。 拥有更新的 commit-graph 文件有助于许多 Git 命令的性能,包括git merge-base
、git push -f
和git log --graph
。 默认为 false。 - fetch.bundleURI
-
此值存储一个 URI,用于在从原始 Git 服务器执行增量式获取之前,从 bundle URI 下载 Git 对象数据。 这类似于 git-clone[1] 中
--bundle-uri
选项的行为方式。 如果提供的 bundle URI 包含为增量式获取组织的 bundle 列表,则git clone --bundle-uri
将设置fetch.bundleURI
值。如果您修改此值并且您的存储库具有
fetch.bundleCreationToken
值,则在从新的 bundle URI 获取之前删除该fetch.bundleCreationToken
值。 - fetch.bundleCreationToken
-
当使用
fetch.bundleURI
从使用 "creationToken" 启发式的 bundle 列表进行增量式获取时,此配置值存储已下载的 bundle 的最大creationToken
值。 如果通告的creationToken
并非严格大于此值,则此值用于阻止将来下载 bundle。创建 token 值由提供特定 bundle URI 的提供程序选择。 如果您修改
fetch.bundleURI
处的 URI,请务必在获取之前删除fetch.bundleCreationToken
值的值。
BUGS
使用 --recurse-submodules 只能获取本地存在的子模块中的新提交,例如在 $GIT_DIR/modules/
中。 如果上游添加了一个新的子模块,则在克隆该子模块之前(例如通过 git submodule update
)无法获取该子模块。 预计这将在未来的 Git 版本中得到修复。
GIT
Part of the git[1] suite