设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
- 2.48.1 → 2.50.1 无更改
-
2.48.0
2025-01-10
- 2.47.2 → 2.47.3 无变更
-
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.4 无更改
-
2.44.0
2024-02-23
- 2.43.1 → 2.43.7 无更改
-
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
来更改。通过使用显式抓取标签的 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=<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
配置选项。 - --[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
不同,它将删除所有已创建的本地引用(本地标签)。此选项是与--prune
一起提供显式标签refspec
的简写,请参阅其文档中的相关讨论。详情请参阅下面的 PRUNING 部分。
- -n
- --no-tags
-
默认情况下,指向从远程仓库下载的对象的标签会被抓取并本地存储。此选项禁用此自动标签跟踪。远程仓库的默认行为可以通过
remote.<name>.tagOpt
设置指定。请参阅 git-config[1]。 - --refetch
-
此选项不是与服务器协商以避免传输本地已存在的提交和相关对象,而是像全新克隆一样抓取所有对象。当过滤器定义更改时,使用此选项可以重新应用配置中的部分克隆过滤器或使用
--filter=
。自动抓取后维护将执行对象数据库包合并以删除任何重复对象。 - --refmap=<refspec>
-
当抓取命令行上列出的引用时,使用指定的 refspec(可以多次给定)将引用映射到远程跟踪分支,而不是使用远程仓库的
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>
-
在“正在抓取子模块 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> 时,它们将按照命令行中列出的顺序全部发送到另一端。当命令行没有给定--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>
中包含*
以表示简单的模式匹配。这样的 refspec 功能类似于匹配任何符合该模式的引用的 glob 模式。一个模式<refspec>
必须在<src>
和<dst>
中都只有一个*
。它将通过将*
替换为源中匹配的内容来将引用映射到目标。如果一个 refspec 以
^
为前缀,它将被解释为负 refspec。这样的 refspec 不指定要抓取哪些引用或要更新哪些本地引用,而是指定要排除的引用。如果一个引用至少匹配一个正 refspec 并且不匹配任何负 refspec,则认为它匹配。负 refspec 对于限制模式 refspec 的范围很有用,使其不包含特定引用。负 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 外,还从标准输入中逐行读取 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>
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-clone[1]。
git
clone
、git
fetch
和 git
pull
(但 git
push
不支持)也会接受合适的捆绑文件。请参阅 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> 参数来代替 URL 使用:
-
Git 配置文件中的远程仓库:
$GIT_DIR/config
, -
$GIT_DIR/remotes
目录中的文件,或 -
$GIT_DIR/branches
目录中的文件。
所有这些也允许你省略命令行中的引用规范,因为它们各自包含一个 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 使用);它们仅通过充当映射来决定抓取到的引用存储在哪里。
remote.
<repository>.fetch
值的后一种用法可以通过在命令行上提供 --refmap=
<refspec> 参数来覆盖。
修剪
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 一起使用时,请务必小心。
由于保持与远程仓库的分支和标签同步是一个常见用例,因此可以 साथ --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
指定),如果 entire
<from> 或 entire
<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
和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])。
安全性
抓取和推送协议并非旨在防止一方从另一方仓库窃取不打算共享的数据。如果您有需要保护免受恶意对等方侵害的私有数据,最佳选择是将其存储在另一个仓库中。这适用于客户端和服务器。特别是,服务器上的命名空间对于读取访问控制无效;您应该只向信任其拥有整个仓库读取访问权限的客户端授予对命名空间的读取访问权限。
已知的攻击向量如下:
-
受害者发送“
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
中的底层抓取)是否会递归抓取到已填充的子模块中。此选项可以设置为布尔值或on-demand
。将其设置为布尔值会更改抓取和拉取的行为:设置为true
时无条件递归到子模块中,设置为false
时完全不递归。当设置为on-demand
时,抓取和拉取将只会在其超项目检索到更新子模块引用的提交时递归到已填充的子模块中。默认为on-demand
,如果设置了submodule.recurse
,则默认为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
,抓取将自动表现为在命令行上给出了--prune
选项。另请参阅remote.
<name>.prune
和 git-fetch[1] 的 PRUNING 部分。 - fetch.pruneTags
-
如果为
true
,如果尚未设置,抓取将自动表现为在修剪时提供了refs/tags/*:refs/tags/*
refspec。这允许同时设置此选项和fetch.prune
,以维护与上游引用的 1:1 映射。另请参阅remote.
<name>.pruneTags
和 git-fetch[1] 的 PRUNING 部分。 - fetch.all
-
如果为
true
,抓取将尝试更新所有可用的远程仓库。此行为可以通过传递--no-all
或显式指定一个或多个要从中抓取的远程仓库来覆盖。默认为false
。 - fetch.output
-
控制引用更新状态的打印方式。有效值为
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
,以便在每次从远程下载包文件的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
不严格大于此值。creationToken
值由提供特定捆绑 URI 的提供者选择。如果您修改fetch.bundleURI
的 URI,则请务必在抓取之前删除fetch.bundleCreationToken
的值。
BUG
使用 --recurse-submodules
只能抓取本地存在的子模块(例如在 $GIT_DIR/modules/
中)中的新提交。如果上游添加了一个新的子模块,该子模块在通过 git
submodule
update
克隆之前无法被抓取。这预计将在未来的 Git 版本中修复。