Setup and Config
Getting and Creating Projects
Basic Snapshotting
Branching and Merging
Sharing and Updating Projects
Inspection and Comparison
Patching
Debugging
External Systems
Server Admin
Guides
- gitattributes
- Command-line interface conventions
- Everyday Git
- Frequently Asked Questions (FAQ)
- Glossary
- Hooks
- gitignore
- gitmodules
- Revisions
- Submodules
- Tutorial
- Workflows
- All guides...
Administration
Plumbing Commands
- 2.44.0 02/23/24
- 2.43.1 → 2.43.3 no changes
- 2.43.0 11/20/23
- 2.42.1 no changes
- 2.42.0 08/21/23
- 2.41.0 06/01/23
- 2.40.1 no changes
- 2.40.0 03/12/23
- 2.38.1 → 2.39.3 no changes
- 2.38.0 10/02/22
- 2.36.1 → 2.37.7 no changes
- 2.36.0 04/18/22
- 2.35.1 → 2.35.8 no changes
- 2.35.0 01/24/22
- 2.33.1 → 2.34.8 no changes
- 2.33.0 08/16/21
- 2.32.1 → 2.32.7 no changes
- 2.32.0 06/06/21
- 2.31.1 → 2.31.8 no changes
- 2.31.0 03/15/21
- 2.29.1 → 2.30.9 no changes
- 2.29.0 10/19/20
- 2.28.1 no changes
- 2.28.0 07/27/20
- 2.27.1 no changes
- 2.27.0 06/01/20
概述
git fetch [<选项>] [<仓库> [<引用规范>…]] git fetch [<选项>] <组> git fetch --multiple [<选项>] [(<仓库> | <组>)…] git fetch --all [<选项>]
描述
Fetch branches and/or tags (collectively, "refs") from one or more other repositories, along with the objects necessary to complete their histories. Remote-tracking branches are updated (see the description of <refspec> below for ways to control this behavior).
By default, any tag that points into the histories being fetched is also fetched; the effect is to fetch tags that point at branches that you are interested in. This default behavior can be changed by using the --tags or --no-tags options or by configuring remote.<name>.tagOpt. By using a refspec that fetches tags explicitly, you can fetch tags that do not point into branches you are interested in as well.
git fetch can fetch from either a single named repository or URL, or from several repositories at once if <group> is given and there is a remotes.<group> entry in the configuration file. (See git-config[1]).
当没有指定远程仓库时,默认情况下将使用 origin
远程仓库,除非有一个上游分支配置在当前分支上。
The names of refs that are fetched, together with the object names they point at, are written to .git/FETCH_HEAD
. This information may be used by scripts or other git commands, such as git-pull[1].
选项
- --[no-]all
-
Fetch all remotes. This overrides the configuration variable
fetch.all
. - -a
- --append
-
Append ref names and object names of fetched refs to the existing contents of
.git/FETCH_HEAD
. Without this option old data in.git/FETCH_HEAD
will be overwritten. - --atomic
-
使用一个原子事务来更新本地索引。要么所有的引用都被更新,要么在出错时,没有引用被更新。
- --depth=<深度>
-
限制从每个远程分支历史的顶端获取指定数量的提交。如果获取的是由
git clone
创建的 浅层 仓库,并使用--depth=<depth>
选项(见 git-clone[1]),则加深或缩短历史,达到指定数量的提交。深化后的提交的标签不会被获取。 - --deepen=<深度>
-
与—depth类似,只是它指定了从当前浅层边界开始的提交数量,而不是从每个远程分支历史的顶端开始。
- --shallow-since=<日期>
-
加深或缩短浅层仓库的历史,包括<日期>之后所有可触及的提交。
- --shallow-exclude=<修订版本>
-
Deepen or shorten the history of a shallow repository to exclude commits reachable from a specified remote branch or tag. This option can be specified multiple times.
- --unshallow
-
如果源仓库是完整的,将浅层资源库转换为完整的仓库,消除浅层仓库带来的所有限制。
如果源仓库是浅层的,尽可能多的获取,使当前仓库的历史与源仓库相同。
- --update-shallow
-
默认情况下,当从浅层仓库获取时,
git fetch
会拒绝需要更新 .git/shallow 的引用。这个选项更新了 .git/shallow 并接受这样的引用。 - --negotiation-tip=<提交|通配符>
-
By default, Git will report, to the server, commits reachable from all local refs to find common commits in an attempt to reduce the size of the to-be-received packfile. If specified, Git will only report commits reachable from the given tips. This is useful to speed up fetches when the user knows which local ref is likely to have commits in common with the upstream ref being fetched.
这个选项可以指定多次;如果是这样,Git将报告从任何一个给定的提交中可达提交。
这个选项的参数可以是一个引用名称的通配符,一个引用,或者一个提交的SHA-1(可能是缩写的)。指定一个通配符相当于多次指定这个选项,为每个匹配的引用名称指定该选项。
参见 git-config[1] 中记录的
fetch.negotiationAlgorithm
和push.negotiate
配置变量,以及下面的--negotiate-only
选项。 - --negotiate-only
-
不从服务器获取任何东西,而是打印所提供的
--negotiation-tip=*
参数与服务器上的共同祖先。This is incompatible with
--recurse-submodules=[yes|on-demand]
. Internally this is used to implement thepush.negotiate
option, see git-config[1]. - --dry-run
-
显示会做什么,而不做任何改变。
- --porcelain
-
将输出结果以易于解析的格式打印到标准输出,供脚本使用。详情见 git-fetch[1] 中的输出部分。
这与
--recurse-submodules=[yes|on-demand]
选项不兼容,并且优先于fetch.output
配置选项。 - --[no-]write-fetch-head
-
Write the list of remote refs fetched in the
FETCH_HEAD
file directly under$GIT_DIR
. This is the default. Passing--no-write-fetch-head
from the command line tells Git not to write the file. Under--dry-run
option, the file is never written. - -f
- --force
-
正如讨论的那样,当 git fetch 与
<源>:<目标>
引用规范一起使用时,它可能会拒绝更新本地分支 在下面的<引用规范>
部分。 这个选项覆盖了这个检查。 - -k
- --keep
-
保存下载的包。
- --multiple
-
允许指定几个 <仓库> 和 <group> 参数。不可以指定 <引用规范>。
- --[no-]auto-maintenance
- --[no-]auto-gc
-
Run
git maintenance run --auto
at the end to perform automatic repository maintenance if needed. (--[no-]auto-gc
is a synonym.) This is enabled by default. - --[no-]write-commit-graph
-
在获取后写一个提交图。这会覆盖
fetch.writeCommitGraph
配置选项。 - --prefetch
-
修改配置的引用规范,将所有引用放到
refs/prefetch/
命名空间中。参见 git-maintenance[1] 中的prefetch
任务。 - -p
- --prune
-
Before fetching, remove any remote-tracking references that no longer exist on the remote. Tags are not subject to pruning if they are fetched only because of the default tag auto-following or due to a --tags option. However, if tags are fetched due to an explicit refspec (either on the command line or in the remote configuration, for example if the remote was cloned with the --mirror option), then they are also subject to pruning. Supplying
--prune-tags
is a shorthand for providing the tag refspec.更多细节见下面的 剪枝 部分。
- -P
- --prune-tags
-
在获取之前,如果
--prune
被启用,则删除任何不再存在于远程的本地标签。这个选项应该更谨慎使用,与`--prune`不同,它将删除任何已经创建的本地引用(本地标签)。这个选项是与`--prune`一起提供明确的标签引用规范的速记形式,见其文档中关于这个的讨论。更多细节见下面的 剪枝 部分。
- -n
- --no-tags
-
By default, tags that point at objects that are downloaded from the remote repository are fetched and stored locally. This option disables this automatic tag following. The default behavior for a remote may be specified with the remote.<name>.tagOpt setting. See git-config[1].
- --refetch
-
这个选项不是与服务器协商以避免传输本地已经存在的提交和相关对象,而是像一个新的克隆那样获取所有对象。当过滤器定义发生变化时,使用此选项重新应用配置中的部分克隆过滤器或使用
--filter=
。自动获取后的维护将执行对象数据库包的整合,以删除任何重复的对象。 - --refmap=<引用规范>
-
When fetching refs listed on the command line, use the specified refspec (can be given more than once) to map the refs to remote-tracking branches, instead of the values of
remote.*.fetch
configuration variables for the remote repository. Providing an empty<refspec>
to the--refmap
option causes Git to ignore the configured refspecs and rely entirely on the refspecs supplied as command-line arguments. See section on "Configured Remote-tracking Branches" for details. - -t
- --tags
-
Fetch all tags from the remote (i.e., fetch remote tags
refs/tags/*
into local tags with the same name), in addition to whatever else would otherwise be fetched. Using this option alone does not subject tags to pruning, even if --prune is used (though tags may be pruned anyway if they are also the destination of an explicit refspec; see--prune
). - --recurse-submodules[=yes|on-demand|no]
-
This option controls if and under what conditions new commits of submodules should be fetched too. When recursing through submodules,
git fetch
always attempts to fetch "changed" submodules, that is, a submodule that has commits that are referenced by a newly fetched superproject commit but are missing in the local submodule clone. A changed submodule can be fetched as long as it is present locally e.g. in$GIT_DIR/modules/
(see gitsubmodules[7]); if the upstream adds a new submodule, that submodule cannot be fetched until it is cloned e.g. bygit submodule update
.当设置为 on-demand 时,只取回已改变的子模块。当设置为 yes 时,所有已填充的子模块都被获取,同时未填充和已改变的子模块也被获取。当设置为 no 时,子模块永远不会被获取。
When unspecified, this uses the value of
fetch.recurseSubmodules
if it is set (see git-config[1]), defaulting to on-demand if unset. When this option is used without any value, it defaults to 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.<名称>.merge
和branch.<名称>.remote
。 - --submodule-prefix=<路径>
-
Prepend <path> to paths printed in informative messages such as "Fetching submodule foo". This option is used internally when recursing over submodules.
- --recurse-submodules-default=[yes|on-demand]
-
This option is used internally to temporarily provide a non-negative default value for the --recurse-submodules option. All other methods of configuring fetch’s submodule recursion (such as settings in gitmodules[5] and git-config[1]) override this option, as does specifying --[no-]recurse-submodules directly.
- -u
- --update-head-ok
-
By default git fetch refuses to update the head which corresponds to the current branch. This flag disables the check. This is purely for the internal use for git pull to communicate with git fetch, and unless you are implementing your own Porcelain you are not supposed to use it.
- --upload-pack <upload-pack>
-
当给出时,并且要获取的仓库是由 git fetch-pack 处理的,
--exec=<upload-pack>
被传递到命令中,为另一端运行的命令指定非默认路径。 - -q
- --quiet
-
将 --quiet 传递给 git-fetch-pack,并使任何其他内部使用的 git 命令保持沉默。进度不会报告给标准错误流。
- -v
- --verbose
-
详细日志。
- --progress
-
当标准错误流连接到终端时,除非指定了 -q,否则默认情况下会在标准错误流上报告进展状态。即使标准错误流没有指向终端,这个标志也会强制显示进度状态。
- -o <选项>
- --server-option=<选项>
-
使用协议版本2进行通信时,将给定的字符串传输到服务器。给定的字符串不得包含NUL或LF字符。服务器对服务器选项(包括未知选项)的处理是取决于服务器。当给出多个`--server-option=<option>`时,它们都按照命令行中列出的顺序发送到另一端。
- --show-forced-updates
-
By default, git checks if a branch is force-updated during fetch. This can be disabled through fetch.showForcedUpdates, but the --show-forced-updates option guarantees this check occurs. See 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>
-
作为获取或拉动操作的来源的 "remote" 仓库。 这个参数可以是一个 URL(见下面 GIT URLS 一节),也可以是一个远程仓库的名称(见下面 REMOTES 一节)。
- <组>
-
指向仓库列表的名称,作为配置文件中 remotes.<组> 的值。 (参见 git-config[1])。
- <refspec>
-
指定要获取哪些引用,以及要更新哪些本地引用。 当命令行上没有出现 <引用规范> 时,将从`remote.<仓库>.fetch` 变量中读取要获取的引用 (see CONFIGURED REMOTE-TRACKING BRANCHES below).
<引用规范> 参数的格式是一个可选的加号
+
,后面是源 <src>,后面是冒号:
,后面是目标引用 <dst>。 当 <dst> 为空时,冒号可以被省略。 <src> 通常是一个引用,但它也可以是一个完全拼写的十六进制对象名称。一个 <引用规范> 可以在其<src>中包含一个`*'来表示一个简单的模式匹配。这样的 refspec 的功能就像一个 glob,可以匹配任何具有相同前缀的 ref。匹配 <引用规范> 必须在 <src> 和 <dst> 中都有一个
*
。它将通过把*
替换成从源头匹配的内容来把引用映射到目的地。如果一个 引用规范的前缀是
^
,它将被解释为一个负向引用规范。这样的引用规范不是指定要获取哪些引用或更新哪些本地引用,而是指定要排除的引用。如果一个引用至少与一个正向引用规范匹配,并且不与任何负向引用规范匹配,那么该引用将被视为匹配。负向引用规范可以用来限制引用规范匹配的范围,使其不包括特定的引用。 负向引用规范本身可以是模式引用规范。然而,它们可能只包含一个 <src>,而不指定一个 <dst>。完全拼出的十六进制对象名称也不被支持。tag <标签>`的意思与`refs/tags/<标签>:refs/tags/<标签>
相同;它要求获取到给定标签的所有内容。获取与 <src> 相匹配的远程引用,如果 <dst> 不是一个空字符串,就会尝试更新与之相匹配的本地引用。
该更新是否允许不使用
--force
,取决于它被获取的引用命名空间、被获取的对象的类型,以及该更新是否被认为是一个快速合并。一般来说,获取的规则与推送的规则相同,参见 git-push[1] 的 ‘<引用规范>…’ 部分。以下是 "git fetch" 特殊规则的例外情况。在 Git 2.20 版本之前,与使用 git-push[1] 推送时不同,任何对
refs/tags/*
的更新都会被接受,在引用规范中没有+
(或`--force`)。在获取的时候,我们把所有来自远程的标签更新都视为强制获取。 从 Git 2.20 版本开始,获取更新refs/tags/*
的方式与推送时相同。也就是说,任何在引用规范中没有+
的更新都会被拒绝(或`--force`)。与使用 git-push[1] 推送时不同,任何在
refs/{tags,heads}/*
之外的更新都会被接受,在引用规范中没有+
(或`--force`),无论是将树对象换成二进制文件,还是将一个提交换成另一个没有前一个提交作为祖先的提交等等。与使用 git-push[1] 推送时不同,没有任何配置可以修改这些规则,也没有类似于
pre-receive
的pre-fetch
钩子。就像用 git-push[1] 推送一样,上面描述的所有关于不允许更新的规则都可以通过在引用规范中添加一个可选的前导词
+
来覆盖(或者使用--force
命令行选项)。唯一的例外是,无论如何强制都不能使refs/heads/*
命名空间接受一个非提交对象。Note当你想获取的远程分支已知会被定期回溯和重定向时,预计它的新提示不会是其先前提示的后代(如你上次获取时存储在远程跟踪分支中的提示)。 你应该使用 +
号来表示对这类分支需要进行非快速合并式更新。 没有办法确定或声明一个分支将以这种行为在仓库中提供;拉取的用户只是必须知道这是一个分支的预期使用模式。
GIT 地址
通常,地址包含有关传输协议,远程服务器的地址以及仓库路径的信息。对于某些传输协议,一些信息可能会缺失。
Git 支持 ssh,git,http 和 https 协议(此外,可以使用 ftp 和 ftps 进行抓取,但这效率低下且不建议使用;请勿使用)。
本地传输(即 git:// URL)不进行身份验证,在不安全的网络上应谨慎使用。
以下是上述几个传输协议的格式:
-
ssh://[user@]host.xz[:port]/path/to/repo.git/
-
git://host.xz[:port]/path/to/repo.git/
-
http[s]://host.xz[:port]/path/to/repo.git/
-
ftp[s]://host.xz[:port]/path/to/repo.git/
ssh 协议也可以使用类似 scp 的语法:
-
[user@]host.xz:path/to/repo.git/
仅当第一个冒号之前没有斜杠时才能识别此语法。这有助于区分包含冒号的本地路径。例如,可以将本地路径 foo:bar
指定为绝对路径,或者将 ./foo:bar
指定为绝对路径,以避免被误识别为 ssh url。
ssh 和 git 协议还支持 ~username 扩展:
-
ssh://[user@]host.xz[:port]/~[user]/path/to/repo.git/
-
git://host.xz[:port]/~[user]/path/to/repo.git/
-
[user@]host.xz:/~[user]/path/to/repo.git/
对于本地仓库(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-<传输方式> 远程帮助程序(如果存在)。要显式请求远程帮助程序,可以使用以下语法:
-
<传送>::<地址>
其中,<地址> 可以是路径,服务器与路径,也可以是可被调用的特定远程帮助程序识别的类似于网页地址的任意字符串。有关详细信息,请参阅 gitremote-helpers[7]。
如果存在大量类似名称的远程仓库,并且您要为其使用不同的格式(这样,您使用的地址将被重写为有效的地址),则可以创建以下形式的配置:
[url "<实际基础网址>"] insteadOf = <其他基础网址>
例如,有如下:
[url "git://git.host.xz/"] insteadOf = host.xz:/path/to/ insteadOf = work:
诸如 "work:repo.git" 或 "host.xz:/path/to/repo.git" 的地址会在任何类似于 "git://git.host.xz/repo" 地址的上下文中重写。
如果要重写仅用于推送的地址,可以创建表单的配置部分:
[url "<实际基础网址>"] pushInsteadOf = <其他基础网址>
例如,有如下:
[url "ssh://example.org/"] pushInsteadOf = git://example.org/
类似于 "git://example.org/path/to/repo.git" 的地址会被重写为 "ssh://example.org/path/to/repo.git",用于推送。但拉取代码时仍然使用原始的地址。
REMOTES[[REMOTES]
可以用下面的一个名称代替URL作为`<repository>`的参数:
-
一个远端的配置文件在此仓库的git配置文件:
$GIT_DIR/config
、 -
这个文件在`$GIT_DIR/remotes`目录下,或者
-
a file in the
$GIT_DIR/branches
directory.
所有这些也允许你从命令行中省略refspec,因为它们都包含一个git默认使用的refspec。
在配置文件中命名为 remote
你可以选择提供你之前用 git-remote[1]、linkgit:git-config[1] 或甚至通过手动编辑 $GIT_DIR/config
文件配置的远程名称。 这个远程的 URL 将被用来访问仓库。 当你没有在命令行上提供引用规范时,这个远程仓库的引用规范将被默认使用。 配置文件中的条目会像这样:
[remote "<name>"] url = <URL> pushurl = <pushurl> push = <refspec> fetch = <refspec>
<pushurl>
仅用于推送。它是可选的,默认为 <URL>
。向远程推送会影响所有定义的推送urls,如果没有定义推送urls,则推送到所有定义的url。然而,如果定义了多个 URL,fetch 将只从第一个定义的 URL 获取。
$GIT_DIR/remotes
中的命名文件
你可以选择提供 $GIT_DIR/remotes
中的文件名。 这个文件中的 URL 将被用来访问仓库。 当你没有在命令行上提供引用规范时,该文件中的引用规范将被作为默认使用。 这个文件应该有以下格式:
URL: one of the above URL format Push: <引用规范> Pull: <引用规范>
Push:
行被 git push 使用,Pull:
行被 git pull 和 git fetch 使用。 可以为额外的分支映射指定多个 Push:
和 Pull:
行。
$GIT_DIR/branches
中的命名文件
你可以选择提供 $GIT_DIR/branches
中的文件名。 这个文件中的 URL 将被用来访问仓库。 这个文件应该有以下格式:
<URL>#<head>
<URL>
是必须的;#<head>
是可选的。
根据不同的操作,如果你没有在命令行上提供一个引用规范,git 会使用以下其中一个。 <分支>
是该文件在 $GIT_DIR/branches
中的名称,<头分支>
默认为 master
。
git fetch 使用:
refs/heads/<头分支>:refs/heads/<分支>。
git push uses:
HEAD:refs/heads/<头分支>。
配置的远程跟踪分支
You often interact with the same remote repository by regularly and repeatedly fetching from it. In order to keep track of the progress of such a remote repository, git fetch
allows you to configure remote.<repository>.fetch
configuration variables.
一般来说,这种变量可能看起来像这样:
[remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/*
这种配置有两种使用方式:
-
When
git fetch
is run without specifying what branches and/or tags to fetch on the command line, e.g.git fetch origin
orgit fetch
,remote.<repository>.fetch
values are used as the refspecs—they specify which refs to fetch and which local refs to update. The example above will fetch all branches that exist in theorigin
(i.e. any ref that matches the left-hand side of the value,refs/heads/*
) and update the corresponding remote-tracking branches in therefs/remotes/origin/*
hierarchy. -
When
git fetch
is run with explicit branches and/or tags to fetch on the command line, e.g.git fetch origin master
, the <refspec>s given on the command line determine what are to be fetched (e.g.master
in the example, which is a short-hand formaster:
, which in turn means "fetch the master branch but I do not explicitly say what remote-tracking branch to update with it from the command line"), and the example command will fetch only the master branch. Theremote.<repository>.fetch
values determine which remote-tracking branch, if any, is updated. When used in this way, theremote.<repository>.fetch
values do not have any effect in deciding what gets fetched (i.e. the values are not used as refspecs when the command-line lists refspecs); they are only used to decide where the refs that are fetched are stored by acting as a mapping.
后者对 remote.<仓库>.fetch
值的使用可以通过在命令行中给出 --refmap=<引用规范>
参数去覆盖。
剪枝
Git默认保留数据,除非它被明确地扔掉;这延伸到保留对远程分支的本地引用,而这些分支本身已经被删除。
如果任其积累,这些陈旧的引用可能会使大型繁忙仓库的性能变差,例如,使 git branch -a --contains <提交>
等命令的输出不必要地冗长,以及影响其他任何与完整的已知引用有关的工作。
这些远程跟踪引用可以通过以下两种方式一次性删除:
# 在获取的时候 $ git fetch --prune <名称> # 只修剪,不获取 $ git remote prune <名称>
要把修剪引用作为正常工作流程的一部分,而不需要记住运行该程序,可以在全局设置 fetch.prune
,或者在配置中设置 remote.<名称>.prune
,为每个远程仓库进行设置。见git-config[1]。
这里是事情变得棘手和更具体的地方。修剪功能实际上并不关心分支,相反,它将修剪本地←→远程引用,作为远程的引用规范的函数(见上面的`<引用规范>`和上面的配置远程跟踪分支)。
因此,如果远程的引用规范包括例如 refs/tags/*:refs/tags/*`这样的规范,或者你手动运行例如 `git fetch --prune <名称> "refs/tags/*:refs/tags/*"
,那么被删除的就不是过时的远程跟踪分支,而是远程上不存在的任何本地标签。
这可能不是你所期望的,即你想修剪远程的 <名称>
,但也明确地从它那里获取标签,所以当你从它那里获取时,你会删除所有的本地标签,其中大部分可能首先不是来自远程的 <名称>
。
因此,当与 refs/tags/*:refs/tags/*
这样的引用规范一起使用时要小心,或者任何其他可能将多个远程的引用映射到同一本地命名空间的引用规范。
由于在远程保持最新的分支和标签是一个常见的使用情况,--prune-tags
选项可以和 --prune
一起使用,以修剪在远程不存在的本地标签,并强制更新那些不同的标签。标签修剪也可以通过配置中的 fetch.pruneTags
或 remote.<名称>.pruneTags
启用。见git-config[1]。
--prune-tags
选项相当于在远程的引用规范中声明 refs/tags/*:refs/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
时修剪标签,这是很合理的,不会使每次调用 git fetch
而没有 --prune
时都出现错误。
使用 --prune-tags
修剪标签,在获取一个URL而不是一个命名的远程时也能发挥作用。这些都会修剪在原点没有发现的标签:
$ 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 协议获取时的输出。
获取的状态以表格的形式输出,每一行代表一个引用的状态。每一行的形式是:
<标志> <概述> <起始> -> <结束> [<原因>]
当使用 --porcelain
时,输出格式的目的是让机器可以解析。与人类可读的输出格式不同,它将打印到标准输出而不是标准错误。每一行都是这样的形式:
<标志> <旧对象ID> <新对象ID> <本地引用>
只有在使用 --verbose 选项时,才会显示最新的引用状态。
在紧凑输出模式下,通过配置变量 fetch.output 指定,如果在另一个字符串中发现整个 <起点>
或 <终点>
,它将被替换成另一个字符串中的 *
。例如,master -> origin/master
变成 master -> origin/*
。
实例
-
更新远程追踪的分支:
$ git fetch origin
上述命令从远程的
refs/heads/
命名空间复制所有分支,并存储到本地的refs/remotes/origin/
命名空间,除非使用remote.<仓库>.fetch
选项来指定一个非默认的引用规范。 -
明确使用引用规范:
$ git fetch origin +seen:seen maint:tmp
This updates (or creates, as necessary) branches
seen
andtmp
in the local repository by fetching from the branches (respectively)seen
andmaint
from the remote repository.即使不快进,
seen
分支也会被更新,因为它的前缀是加号;tmp
则不会。 -
窥视一个远程的分支,而不需要在你的本地版本库中配置远程:
$ git fetch git://git.kernel.org/pub/scm/git/git.git maint $ git log FETCH_HEAD
The first command fetches the
maint
branch from the repository atgit://git.kernel.org/pub/scm/git/git.git
and the second command usesFETCH_HEAD
to examine the branch with git-log[1]. The fetched objects will eventually be removed by git’s built-in housekeeping (see git-gc[1]).
安全
获取和推送协议并不是为了防止一方从另一个版本库窃取不打算共享的数据。如果你有需要保护的私人数据不被恶意的同行窃取,你最好的选择是把它存储在另一个资源库中。这同时适用于客户端和服务器。特别是,服务器上的命名空间对于读取访问控制是无效的;你应该只将命名空间的读取访问权授予那些你信任的可以读取整个版本库的客户。
已知的攻击媒介如下:
-
受害者发送 "have" 行,宣传它所拥有的对象的 ID,这些对象并没有明确地打算被共享,但如果对等体也有这些对象,就可以用来优化传输。攻击者选择了一个对象 ID X 来窃取,并向 X 发送了一个引用,但不需要发送 X 的内容,因为受害者已经拥有它。现在,受害者认为攻击者拥有 X,它稍后将 X 的内容发回给攻击者。(这种攻击对于客户端来说在服务器上执行是最直接的,通过在客户端可以访问的命名空间中创建一个 X 的引用,然后获取它。服务器最可能在客户端执行的方式是将 X "合并" 到一个公共分支,并希望用户在这个分支上做额外的工作,然后在没有注意到合并的情况下将其推回给服务器。)
-
As in #1, the attacker chooses an object ID X to steal. The victim sends an object Y that the attacker already has, and the attacker falsely claims to have X and not Y, so the victim sends Y as a delta against X. The delta reveals regions of X that are similar to Y to the attacker.
配置
Warning
|
Missing See original version for this content. |
Warning
|
Missing See original version for this content. |
漏洞
使用 --recurse-submodules 只能获取本地存在的子模块中的新提交,例如在 $GIT_DIR/modules/
。如果上游添加了一个新的子模块,该子模块不能被获取,直到它被克隆,例如,通过`git submodule update`。这个问题有望在未来的 Git 版本中被修复。
GIT
属于 git[1] 文档