Git
简体中文 ▾ Topics ▾ Latest version ▾ git-fetch last updated in 2.44.0

名称

git-fetch - 从另一个仓库下载对象和引用

概述

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.negotiationAlgorithmpush.negotiate 配置变量,以及下面的 --negotiate-only 选项。

--negotiate-only

不从服务器获取任何东西,而是打印所提供的 --negotiation-tip=* 参数与服务器上的共同祖先。

This is incompatible with --recurse-submodules=[yes|on-demand]. Internally this is used to implement the push.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. by git 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.parallelsubmodule.fetchJobs(见git-config[1])。

通常情况下,并行的递归和多远程的提取会更快。默认情况下,检索是按顺序进行的,而不是并行的。

--no-recurse-submodules

禁用子模块的递归获取(这与使用 --recurse-submodules=no 选项的效果相同)。

--set-upstream

如果远程被成功获取,添加上游(跟踪)引用,由无参数的 git-pull[1] 和其他命令使用。更多信息,见 git-config[1] 中的 branch.<名称>.mergebranch.<名称>.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-receivepre-fetch 钩子。

就像用 git-push[1] 推送一样,上面描述的所有关于不允许更新的规则都可以通过在引用规范中添加一个可选的前导词 + 来覆盖(或者使用 --force 命令行选项)。唯一的例外是,无论如何强制都不能使 refs/heads/* 命名空间接受一个非提交对象。

Note
当你想获取的远程分支已知会被定期回溯和重定向时,预计它的新提示不会是其先前提示的后代(如你上次获取时存储在远程跟踪分支中的提示)。 你应该使用 + 号来表示对这类分支需要进行非快速合并式更新。 没有办法确定或声明一个分支将以这种行为在仓库中提供;拉取的用户只是必须知道这是一个分支的预期使用模式。
--stdin

从stdin中读取引用规范,每行一个,除了作为参数提供的那些之外。不支持 "标签 <名称>" 格式。

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 clonegit fetchgit 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 pullgit 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 or git 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 the origin (i.e. any ref that matches the left-hand side of the value, refs/heads/*) and update the corresponding remote-tracking branches in the refs/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 for master:, 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. The remote.<repository>.fetch values determine which remote-tracking branch, if any, is updated. When used in this way, the remote.<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.pruneTagsremote.<名称>.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/*

标志

表示引用状态的单个字符:

(空格)

表示成功的快速合并;

+

表示一个成功的强制更新;

-

表示成功修剪引用;

t

表示成功更新标签;

*

表示成功获取新引用;

!

表示被拒绝或更新失败的引用;以及

=

表示一个最新的、不需要获取的引用。

概述

对于一个成功获取的引用,摘要以适合作为 git log 参数的形式显示该引用的新旧值(在大多数情况下是 <旧>..<新>,对于强制非快速合并是 <旧>...<新>)。

起始

被获取的远程引用的名称,减去其`refs/<类型>/`前缀。在删除的情况下,远程引用的名称是 "(none)"。

结束

被更新的本地引用的名称,去掉其 refs/<类型>/ 前缀。

原因

一个人类可读的解释。如果是成功获取的引用,不需要解释。对于失败的引用,将描述失败的原因。

实例

  • 更新远程追踪的分支:

    $ 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 and tmp in the local repository by fetching from the branches (respectively) seen and maint 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 at git://git.kernel.org/pub/scm/git/git.git and the second command uses FETCH_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]).

安全

获取和推送协议并不是为了防止一方从另一个版本库窃取不打算共享的数据。如果你有需要保护的私人数据不被恶意的同行窃取,你最好的选择是把它存储在另一个资源库中。这同时适用于客户端和服务器。特别是,服务器上的命名空间对于读取访问控制是无效的;你应该只将命名空间的读取访问权授予那些你信任的可以读取整个版本库的客户。

已知的攻击媒介如下:

  1. 受害者发送 "have" 行,宣传它所拥有的对象的 ID,这些对象并没有明确地打算被共享,但如果对等体也有这些对象,就可以用来优化传输。攻击者选择了一个对象 ID X 来窃取,并向 X 发送了一个引用,但不需要发送 X 的内容,因为受害者已经拥有它。现在,受害者认为攻击者拥有 X,它稍后将 X 的内容发回给攻击者。(这种攻击对于客户端来说在服务器上执行是最直接的,通过在客户端可以访问的命名空间中创建一个 X 的引用,然后获取它。服务器最可能在客户端执行的方式是将 X "合并" 到一个公共分支,并希望用户在这个分支上做额外的工作,然后在没有注意到合并的情况下将其推回给服务器。)

  2. 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 zh_HANS-CN/includes/cmd-config-section-all.txt

See original version for this content.

Warning

Missing zh_HANS-CN/config/fetch.txt

See original version for this content.

漏洞

使用 --recurse-submodules 只能获取本地存在的子模块中的新提交,例如在 $GIT_DIR/modules/。如果上游添加了一个新的子模块,该子模块不能被获取,直到它被克隆,例如,通过`git submodule update`。这个问题有望在未来的 Git 版本中被修复。

参见

GIT

属于 git[1] 文档

scroll-to-top