git-pull

原文: https://git-scm.com/docs/git-pull

名称

git-pull - 从另一个存储库或本地分支获取并与其集成

概要

  1. git pull [<options>] [<repository> [<refspec>…​]]

描述

将来自远程存储库的更改合并到当前分支中。在默认模式下,git pullgit fetch的缩写,后跟git merge FETCH_HEAD

更确切地说, git pull 使用给定参数运行 git fetch 并调用 git merge 将检索到的分支头合并到当前分支中。使用--rebase,它运行 git rebase 而不是 git merge

<库>应该是传递给 git-fetch [1] 的远程存储库的名称。 <的Refspec>可以命名任意远程引用(例如,标记的名称),甚至是具有相应远程跟踪分支的引用集合(例如,refs / heads / :refs / remotes / origin / ),但通常它是远程存储库中分支的名称。

< repository>的默认值和< branch>从 git-branch [1] --track设置的当前分支的“远程”和“合并”配置中读取。

假设存在以下历史记录,当前分支为“master”:

  1. A---B---C master on origin
  2. /
  3. D---E---F---G master
  4. ^
  5. origin/master in your repository

然后“git pull”将从远程master分支获取并重放更改,因为它偏离本地master(即E),直到它在master之上的当前提交(C)并将结果记录在新提交中,同时记录两个父提交的名称以及描述更改的用户的日志消息。

  1. A---B---C origin/master
  2. / \
  3. D---E---F---G---H master

有关详细信息,请参阅 git-merge [1] ,包括如何呈现和处理冲突。

在Git 1.7.0或更高版本中,要取消冲突的合并,请使用git reset --merge警告:在旧版本的Git中,不鼓励使用未提交的更改运行 git pull :尽管可能,它会使您处于可能难以退出的状态冲突

如果任何远程更改与本地未提交的更改重叠,则将自动取消合并并且不更改工作树。通过 git-stash [1] 拉动或存放它们之前,通常最好在工作顺序中进行任何局部更改。

OPTIONS

  1. -q
  1. --quiet

这将传递给基础git-fetch以在传输过程中进行静噪报告,并在合并期间将基础git-merge传递给静噪输出。

  1. -v
  1. --verbose

传递—verbose到git-fetch和git-merge。

  1. --[no-]recurse-submodules[=yes|on-demand|no]

此选项控制是否应该获取和更新所有已填充子模块的新提交(请参阅 git-config [1]gitmodules [5] )。

如果通过rebase完成检出,则本地子模块提交也会被重新设置。

如果通过合并完成更新,则解析并检出子模块冲突。

与合并相关的选项

  1. --commit
  1. --no-commit

执行合并并提交结果。此选项可用于覆盖—no-commit。

使用—no-commit执行合并但假装合并失败并且不自动提交,以便让用户有机会在提交之前检查并进一步调整合并结果。

  1. --edit
  1. -e
  1. --no-edit

在提交成功的机械合并之前调用编辑器以进一步编辑自动生成的合并消息,以便用户可以解释并证明合并。 --no-edit选项可用于接受自动生成的消息(通常不鼓励这样做)。

较旧的脚本可能取决于不允许用户编辑合并日志消息的历史行为。他们将在运行git merge时看到编辑器打开。为了便于将此类脚本调整为更新的行为,可以在环境变量GIT_MERGE_AUTOEDIT的开头设置为no

  1. --ff

当合并解析为快进时,仅更新分支指针,而不创建合并提交。这是默认行为。

  1. --no-ff

即使合并解析为快进,也要创建合并提交。这是在 refs / tags / 层次结构中合并未存储在其自然位置的带注释(且可能已签名)的标记时的默认行为。

  1. --ff-only

拒绝以非零状态合并和退出,除非当前HEAD已经是最新的,或者合并可以解析为快进。

  1. -S[<keyid>]
  1. --gpg-sign[=<keyid>]

GPG签署生成的合并提交。 keyid参数是可选的,默认为提交者标识;如果指定,它必须粘在没有空格的选项上。

  1. --log[=<n>]
  1. --no-log

除了分支名称之外,还使用最多< n>的单行描述填充日志消息。正在合并的实际提交。另见 git-fmt-merge-msg [1]

使用—no-log不会列出正在合并的实际提交中的单行描述。

  1. --signoff
  1. --no-signoff

在提交日志消息的末尾由提交者添加逐行签名。签收的含义取决于项目,但它通常证明提交者有权在同一许可下提交此作品并同意开发者原产地证书(参见 http://developercertificate.org/ ] 欲获得更多信息)。

使用—no-signoff时不要添加Sign-off-by行。

  1. --stat
  1. -n
  1. --no-stat

在合并结束时显示diffstat。 diffstat也由配置选项merge.stat控制。

使用-n或—no-stat时,在合并结束时不显示diffstat。

  1. --squash
  1. --no-squash

生成工作树和索引状态,就好像发生了真正的合并(合并信息除外),但实际上没有提交,移动HEAD或记录$GIT_DIR/MERGE_HEAD(导致下一个git commit命令到创建合并提交)。这允许您在当前分支之上创建单个提交,其效果与合并另一个分支(或章鱼的情况下更多)相同。

使用—no-squash执行合并并提交结果。此选项可用于覆盖—squash。

  1. -s <strategy>
  1. --strategy=<strategy>

使用给定的合并策略;可以多次提供,以按照应该尝试的顺序指定它们。如果没有-s选项,则使用内置的策略列表(合并单个头时 git merge-recursive ,否则使用 git merge-octopus )。

  1. -X <option>
  1. --strategy-option=<option>

将合并策略特定选项传递给合并策略。

  1. --verify-signatures
  1. --no-verify-signatures

验证正在合并的侧分支的提示提交是否使用有效密钥签名,即具有有效uid的密钥:在默认信任模型中,这意味着签名密钥已由可信密钥签名。如果侧分支的提示提交未使用有效密钥签名,则合并将中止。

  1. --summary
  1. --no-summary

同义词—stat和—no-stat;这些已被弃用,将来会被删除。

  1. --allow-unrelated-histories

默认情况下,git merge命令拒绝合并不共享共同祖先的历史记录。在合并独立开始生命的两个项目的历史时,此选项可用于覆盖此安全性。由于这是一种非常罕见的情况,因此默认情况下不会启用任何配置变量来启用它,也不会添加。

  1. -r
  1. --rebase[=false|true|merges|preserve|interactive]

如果为true,则在获取后将当前分支重新绑定在上游分支的顶部。如果存在与上游分支对应的远程跟踪分支,并且自上次提取以来上游分支已重新定位,则rebase使用该信息来避免重新定位非本地更改。

设置为merges时,使用git rebase --rebase-merges进行rebase,以便本地合并提交包含在rebase中(有关详细信息,请参阅 git-rebase [1] )。

设置为preserve时,将--preserve-merges选项的rebase传递给git rebase,以便本地创建的合并提交不会被展平。

如果为false,则将当前分支合并到上游分支中。

interactive时,启用rebase的交互模式。

如果要使git pull始终使用--rebase而不是合并,请参见 git-config [1] 中的pull.rebasebranch.&lt;name&gt;.rebasebranch.autoSetupRebase

| 注意 | 这是一种潜在的危险操作模式。它重写了历史,当你已经发布了这段历史时,它并不是一个好兆头。除非您仔细阅读 git-rebase [1] ,否则不能使用此选项。 |

  1. --no-rebase

先覆盖—rebase。

  1. --autostash
  1. --no-autostash

在开始rebase之前,根据需要隐藏本地修改(参见 git-stash [1] ),并在完成后应用存储条目。 --no-autostash用于覆盖rebase.autoStash配置变量(参见 git-config [1] )。

此选项仅在使用“—rebase”时有效。

与获取相关的选项

  1. --all

获取所有遥控器。

  1. -a
  1. --append

将获取的引用的引用名称和对象名称附加到.git/FETCH_HEAD的现有内容。如果没有此选项,.git/FETCH_HEAD中的旧数据将被覆盖。

  1. --depth=<depth>

从每个远程分支历史记录的提示限制提取到指定的提交数。如果使用--depth=&lt;depth&gt;选项(参见 git-clone [1] )获取git clone创建的存储库,请将历史记录加深或缩短到指定的提交数。不提取深化提交的标记。

  1. --deepen=<depth>

与—depth类似,不同之处在于它指定了当前浅边界而不是每个远程分支历史记录的提交数。

  1. --shallow-since=<date>

深化或缩短浅存储库的历史记录,以包括< date>之后的所有可访问提交。

  1. --shallow-exclude=<revision>

深化或缩短浅存储库的历史记录,以排除从指定的远程分支或标记可到达的提交。可以多次指定此选项。

  1. --unshallow

如果源存储库已完成,请将浅存储库转换为完整存储库,从而消除浅存储库所施加的所有限制。

如果源存储库很浅,则尽可能多地获取,以便当前存储库与源存储库具有相同的历史记录。

  1. --update-shallow

默认情况下,从浅存储库中获取时,git fetch拒绝需要更新.git / shallow的引用。此选项更新.git / shallow并接受此类引用。

  1. --negotiation-tip=<commit|glob>

默认情况下,Git将向服务器报告可从所有本地引用访问的提交,以查找公共提交以尝试减少要接收的包文件的大小。如果指定,Git将仅报告从给定提示可到达的提交。当用户知道哪个本地ref可能与正在获取的上游引用有共同提交时,这对于加速提取是有用的。

可以多次指定此选项;如果是这样,Git将报告从任何给定提交可到达的提交。

此选项的参数可以是ref的名称,ref或者提交的(可能缩写的)SHA-1上的glob。指定glob等效于多次指定此选项,每个匹配的ref名称一个。

另请参见 git-config [1] 中记录的fetch.negotiationAlgorithm配置变量。

  1. -f
  1. --force

git fetch&lt;src&gt;:&lt;dst&gt; refspec一起使用时,它可能会拒绝更新本地分支,如 git-fetch [1] 文档的&lt;refspec&gt;部分所述。此选项会覆盖该检查。

  1. -k
  1. --keep

保持下载的包。

  1. --no-tags

默认情况下,指向从远程存储库下载的对象的标记将被提取并存储在本地。此选项会禁用此自动标记。可以使用远程。< name> .tagOpt设置指定远程的默认行为。见 git-config [1]

  1. -u
  1. --update-head-ok

默认情况下 git fetch 拒绝更新与当前分支对应的头部。此标志禁用检查。这纯粹是为 git pull 内部使用与 git fetch 进行通信,除非你实现自己的瓷器,否则你不应该使用它。

  1. --upload-pack <upload-pack>

当给定,并且要获取的存储库由 git fetch-pack 处理时,--exec=&lt;upload-pack&gt;被传递给命令以指定另一端运行的命令的非默认路径。

  1. --progress

除非指定了-q,否则在将标准错误流附加到终端时,默认情况下会报告进度状态。即使标准错误流未定向到终端,此标志也会强制进度状态。

  1. -o <option>
  1. --server-option=<option>

使用协议版本2进行通信时,将给定的字符串传输到服务器。给定的字符串不得包含NUL或LF字符。当给出多个--server-option=&lt;option&gt;时,它们都按照命令行中列出的顺序发送到另一侧。

  1. -4
  1. --ipv4

仅使用IPv4地址,忽略IPv6地址。

  1. -6
  1. --ipv6

仅使用IPv6地址,忽略IPv4地址。

  1. <repository>

“远程”存储库,它是获取或拉取操作的源。该参数可以是URL(参见下面的 GIT URL 部分)或遥控器的名称(参见下面的 REMOTES 部分)。

  1. <refspec>

指定要获取的引用和要更新的本地引用。如果命令行中没有< refspec> s,则从remote.&lt;repository&gt;.fetch变量读取reff to fetch(参见 git-fetch [1] )。

< refspec>的格式参数是可选加+,后跟源< src>,后跟冒号:,后跟目标ref< dst>。当< dst>时,可以省略冒号。是空的。 < SRC>通常是ref,但它也可以是完全拼写的十六进制对象名称。

tag &lt;tag&gt;表示与refs/tags/&lt;tag&gt;:refs/tags/&lt;tag&gt;相同;它请求获取给定标记的所有内容。

匹配< src>的远程引用取出,如果< dst>不是空字符串,尝试更新与其匹配的本地引用。

在没有--force的情况下是否允许更新取决于它被提取到的ref命名空间,被提取的对象的类型,以及更新是否被认为是快进。通常,相同的规则适用于推送时的提取,请参阅 git-push [1]&lt;refspec&gt;...部分。 git fetch 特有的那些规则的例外情况如下所述。

直到Git版本2.20,并且与使用 git-push [1] 推送时不同,对refs/tags/*的任何更新都将在refspec(或--force)中没有+的情况下被接受。在获取时,我们会混淆地将远程的所有标记更新视为强制提取。从Git版本2.20开始,获取更新refs/tags/*的方式与推送时相同。即如果没有refspec(或--force)中的+,任何更新都将被拒绝。

与使用 git-push [1] 进行推送时不同,[refdpec(或--force)中的+将接受refs/{tags,heads}/*以外的任何更新,无论是否交换,例如一个blob的树对象,或另一个提交的提交,它没有先前的提交作为祖先等。

与使用 git-push [1] 进行推送不同,没有任何配置可以修改这些规则,也没有类似于pre-receive挂钩的pre-fetch挂钩。

与使用 git-push [1] 推送一样,可以通过向refspec添加可选的前导+(或使用--force来覆盖上面描述的关于不允许作为更新的所有规则。 ]命令行选项)。唯一的例外是没有任何强制将使refs/heads/*命名空间接受非提交对象。

| 注意 | 当你想要获取的远程分支被认为是经常倒带和重新定位时,预计它的新提示将不会是其上一个提示的后代(如上次提取时存储在远程跟踪分支中)。您可能希望使用+符号来指示此类分支将需要非快进更新。无法确定或声明具有此行为的存储库中的分支可用;拉动用户只需知道这是分支的预期使用模式。 |

| 注意 | 列出多个< refspec>之间存在差异直接在 git pull 命令行上,并在您的配置中为< repository>提供多个remote.&lt;repository&gt;.fetch条目并运行 git pull 命令,没有任何明确的< refspec>参数。在命令行中明确列出的< refspec>在获取后始终合并到当前分支中。换句话说,如果列出多个远程引用, git pull 将创建一个Octopus合并。另一方面,如果你没有列出任何明确的< refspec>在命令行上的参数, git pull 将获取它在remote.&lt;repository&gt;.fetch配置中找到的所有< refspec> s并仅合并第一个< refspec>找到了当前的分支。这是因为很少使用远程参考设备制作八达通,而通过提取一个以上来一次跟踪多个远程磁头通常很有用。 |

GIT网址

通常,URL包含有关传输协议,远程服务器的地址以及存储库路径的信息。根据传输协议,可能缺少某些信息。

Git支持ssh,git,http和https协议(此外,ftp和ftps可用于获取,但这是低效的并且已弃用;请勿使用它)。

本机传输(即git:// URL)不进行身份验证,应在不安全的网络上谨慎使用。

可以使用以下语法:

  • SSH:// [用户@] host.xz [:端口] /path/to/repo.git/

  • GIT中://host.xz [:端口] /path/to/repo.git/

  • HTTP [S]://host.xz [:端口] /path/to/repo.git/

  • FTP [S]://host.xz [:端口] /path/to/repo.git/

另一种类似scp的语法也可以与ssh协议一起使用:

  • [用户@] host.xz:路径/到/ repo.git /

只有在第一个冒号之前没有斜杠时才会识别此语法。这有助于区分包含冒号的本地路径。例如,本地路径foo:bar可以指定为绝对路径或./foo:bar,以避免被误解为ssh url。

ssh和git协议还支持〜用户名扩展:

  • SSH:// [用户@] host.xz [:端口] /〜[用户] /path/to/repo.git/

  • GIT中://host.xz [:端口] /〜[用户] /path/to/repo.git/

  • [用户@] host.xz:/〜[用户] /path/to/repo.git/

对于本地也受Git支持的本地存储库,可以使用以下语法:

  • /path/to/repo.git/

  • 文件:///path/to/repo.git/

这两种语法大多是等价的,除了克隆时,前者暗示—local选项。有关详细信息,请参阅 git-clone [1]

当Git不知道如何处理某种传输协议时,它会尝试使用 remote-< transport> 远程助手,如果存在的话。要显式请求远程帮助程序,可以使用以下语法:

  • <运输> ::<地址>

其中<地址>可以是路径,服务器和路径,或者由被调用的特定远程助手识别的任意类似URL的字符串。有关详细信息,请参阅 gitremote-helpers [1]

如果存在大量具有相似名称的远程存储库,并且您希望为它们使用不同的格式(以便将您使用的URL重写为有效的URL),则可以创建表单的配置部分:

  1. [url "<actual url base>"]
  2. insteadOf = <other url base>

例如,有了这个:

  1. [url "git://git.host.xz/"]
  2. insteadOf = host.xz:/path/to/
  3. insteadOf = work:

像“work:repo.git”这样的URL或类似“host.xz:/path/to/repo.git”的URL将在任何带有URL的上下文中被重写为“git://git.host.xz/repo” git的”。

如果要为仅推送重写URL,可以创建表单的配置部分:

  1. [url "<actual url base>"]
  2. pushInsteadOf = <other url base>

例如,有了这个:

  1. [url "ssh://example.org/"]
  2. pushInsteadOf = git://example.org/

像“git://example.org/path/to/repo.git”这样的网址将被重写为“ssh://example.org/path/to/repo.git”以进行推送,但是pull仍会使用原始网址。

遥控

可以使用以下某个名称而不是URL作为&lt;repository&gt;参数:

  • Git配置文件中的一个遥控器:$GIT_DIR/config

  • $GIT_DIR/remotes目录中的文件,或

  • $GIT_DIR/branches目录中的文件。

所有这些也允许你从命令行省略refspec,因为它们每个都包含一个git将默认使用的refspec。

在配置文件中命名为remote

您可以选择使用 git-remote [1]git-config [1] 提供之前配置的遥控器的名称,甚至可以手动编辑$GIT_DIR/config文件。此远程的URL将用于访问存储库。如果未在命令行上提供refspec,则默认情况下将使用此远程的refspec。配置文件中的条目如下所示:

  1. [remote "<name>"]
  2. url = <url>
  3. pushurl = <pushurl>
  4. push = <refspec>
  5. fetch = <refspec>

&lt;pushurl&gt;仅用于推送。它是可选的,默认为&lt;url&gt;

$GIT_DIR/remotes中的命名文件

您可以选择在$GIT_DIR/remotes中提供文件名。此文件中的URL将用于访问存储库。如果未在命令行上提供refspec,则此文件中的refspec将用作默认值。该文件应具有以下格式:

  1. URL: one of the above URL format
  2. Push: <refspec>
  3. Pull: <refspec>

git push 使用Push:行, git pullgit fetch 使用Pull:系。可以为其他分支映射指定多个Push:Pull:行。

$GIT_DIR/branches中的命名文件

您可以选择在$GIT_DIR/branches中提供文件名。此文件中的URL将用于访问存储库。该文件应具有以下格式:

  1. <url>#<head>

&lt;url&gt;是必需的; #&lt;head&gt;是可选的。

根据操作,如果您没有在命令行上提供一个refitpec,git将使用以下refspec之一。 &lt;branch&gt;$GIT_DIR/branches中此文件的名称,&lt;head&gt;默认为master

git fetch使用:

  1. refs/heads/<head>:refs/heads/<branch>

git push使用:

  1. HEAD:refs/heads/<head>

合并战略

合并机制(git mergegit pull命令)允许使用-s选项选择后端合并策略。一些策略也可以采用自己的选项,可以通过向git merge和/或git pull提供-X&lt;option&gt;参数来传递。

  1. resolve

这只能使用3向合并算法解析两个头(即当前分支和您从中拉出的另一个分支)。它试图仔细检测纵横交错的合并模糊,并且通常被认为是安全和快速的。

  1. recursive

这只能使用3向合并算法解析两个磁头。当有多个可用于3向合并的共同祖先时,它会创建共同祖先的合并树,并将其用作3向合并的参考树。据报道,这会导致更少的合并冲突,而不会因为从Linux 2.6内核开发历史记录中进行的实际合并提交所做的测试而导致错误。此外,这可以检测和处理涉及重命名的合并,但目前无法使用检测到的副本。这是拉动或合并一个分支时的默认合并策略。

递归策略可以采用以下选项:

  1. ours

这个选项通过支持我们的版本来强制冲突的帅哥干净地自动解决。来自与我们方不冲突的其他树的更改将反映到合并结果中。对于二进制文件,整个内容都来自我们这边。

这不应该与我们的合并策略混淆,后者甚至不会查看其他树包含的内容。它丢弃了另一棵树所做的一切,声明我们的历史记录中包含了所有发生的事情。

  1. theirs

这与我们的相反;请注意,与我们的不同,没有他们的合并策略来混淆这个合并选项。

  1. patience

使用此选项, merge-recursive 花费一点额外的时间来避免由于不重要的匹配行(例如,来自不同函数的大括号)而有时发生的错误。当要合并的分支发生疯狂分歧时使用此选项。另见 git-diff [1] --patience

  1. diff-algorithm=[patience|minimal|histogram|myers]

告诉 merge-recursive 使用不同的diff算法,这有助于避免由于不重要的匹配行(例如来自不同函数的大括号)而发生的错误。另见 git-diff [1] --diff-algorithm

  1. ignore-space-change
  1. ignore-all-space
  1. ignore-space-at-eol
  1. ignore-cr-at-eol

为了进行三向合并,将具有指示类型的空白的行更改为未更改。与空行的其他更改混合的空白更改不会被忽略。另见 git-diff [1] -b-w--ignore-space-at-eol--ignore-cr-at-eol

  • 如果他们的版本只将空格更改引入一行,我们的版本被使用;

  • 如果我们的版本引入了空格更改,但他们的版本包含了实质性更改,使用了他们的版本;

  • 否则,合并以通常的方式进行。

  1. renormalize

在解析三向合并时,这将运行虚拟签出并检入文件的所有三个阶段。此选项适用于将分支与不同的清除过滤器或行尾规范化规则合并时使用。有关详细信息,请参阅 gitattributes [5] 中的“合并具有不同签入/签出属性的分支”。

  1. no-renormalize

禁用renormalize选项。这会覆盖merge.renormalize配置变量。

  1. no-renames

关闭重命名检测。这会覆盖merge.renames配置变量。另见 git-diff [1] --no-renames

  1. find-renames[=<n>]

打开重命名检测,可选择设置相似性阈值。这是默认值。这会覆盖 merge.renames 配置变量。另见 git-diff [1] --find-renames

  1. rename-threshold=<n>

已弃用find-renames=&lt;n&gt;的同义词。

  1. subtree[=<path>]

此选项是子树策略的更高级形式,其中策略猜测两个树在合并时必须如何移位以相互匹配。相反,指定的路径是前缀(或从头开始剥离),以使两个树的形状匹配。

  1. octopus

这解决了具有两个以上磁头的情况,但拒绝执行需要手动解决的复杂合并。它主要用于将主题分支头捆绑在一起。这是拉动或合并多个分支时的默认合并策略。

  1. ours

这会解析任意数量的头,但合并的结果树始终是当前分支头的树,实际上忽略了所有其他分支的所有更改。它旨在用于取代侧枝的旧发展历史。请注意,这与递归合并策略的-Xours选项不同。

  1. subtree

这是一种修改后的递归策略。当合并树A和B时,如果B对应于A的子树,则首先调整B以匹配A的树结构,而不是读取相同级别的树。这种调整也是对共同的祖先树进行的。

使用三向合并的策略(包括默认的递归),如果在两个分支上进行了更改,但稍后在其中一个分支上进行了更改,则该更改将出现在合并结果中;有些人发现这种行为令人困惑。之所以会发生这种情况,是因为在执行合并时只考虑头和合并基础,而不是单个提交。因此,合并算法将恢复的更改视为完全没有更改,而是替换更改的版本。

违约行为

通常人们使用git pull而不给出任何参数。传统上,这相当于说git pull origin。但是,当在分支&lt;name&gt;上存在配置branch.&lt;name&gt;.remote时,将使用该值代替origin

为了确定用于获取的URL,请参考配置remote.&lt;origin&gt;.url的值,如果没有任何此类变量,则使用$GIT_DIR/remotes/&lt;origin&gt;URL:行的值。

为了确定在命令行上没有任何refspec参数的情况下运行命令时要获取(并且可选地存储在远程跟踪分支中)的远程分支,将查询配置变量remote.&lt;origin&gt;.fetch的值,如果没有t any,咨询$GIT_DIR/remotes/&lt;origin&gt;并使用其Pull:线。除了OPTIONS部分中描述的refspec格式之外,您还可以使用如下所示的globbing refspec:

  1. refs/heads/*:refs/remotes/origin/*

globbing refspec必须具有非空RHS(即必须存储在远程跟踪分支中获取的内容),并且其LHS和RHS必须以/*结束。以上规定了使用相同名称的refs/remotes/origin/层次结构中的远程跟踪分支跟踪所有远程分支。

在获取之后确定要合并哪个远程分支的规则有点涉及,以便不破坏向后兼容性。

如果在git pull的命令行上给出了显式refspec,则它们都被合并。

如果命令行上没有给出refspec,则git pull使用配置中的refspec或$GIT_DIR/remotes/&lt;origin&gt;。在这种情况下,以下规则适用:

  1. 如果当前分支&lt;name&gt;branch.&lt;name&gt;.merge配置存在,那么这是合并的远程站点的分支的名称。

  2. 如果refspec是一个全局的,则不会合并任何内容。

  3. 否则,合并第一个refspec的远程分支。

例子

  • 更新克隆的存储库的远程跟踪分支,然后将其中一个合并到当前分支中:

    1. $ git pull
    2. $ git pull origin

    通常,合并的分支是远程存储库的HEAD,但选择由分支确定。< name> .remote和branch。< name> .merge options;有关详细信息,请参阅 git-config [1]

  • 合并到当前分支远程分支next

    1. $ git pull origin next

    这会在FETCH_HEAD中暂时保留next的副本,但不会更新任何远程跟踪分支。使用远程跟踪分支,可以通过调用fetch和merge来完成相同的操作:

    1. $ git fetch origin
    2. $ git merge origin/next

如果您尝试拉动导致复杂冲突并且想要重新开始,则可以使用 git reset 进行恢复。

安全

提取和推送协议的目的不是为了防止一方窃取不打算共享的其他存储库中的数据。如果您需要保护私有数据免受恶意对等方的攻击,那么最佳选择是将其存储在另一个存储库中。这适用于客户端和服务器。特别是,服务器上的命名空间对读访问控制无效;您应该只将命名空间的读访问权授予您信任的客户端,并具有对整个存储库的读访问权限。

已知的攻击向量如下:

  1. 受害者发送“有”行,宣传其拥有的对象的ID,这些对象并未明确地用于共享,但如果对等方也拥有它们,则可用于优化转移。攻击者选择一个对象ID X来窃取并向X发送一个ref,但不需要发送X的内容,因为受害者已经拥有它。现在,受害者认为攻击者拥有X,并且稍后会将X的内容发送回攻击者。 (这种攻击对于客户端在服务器上执行是最直接的,通过在客户端有权访问的命名空间中创建ref,然后获取它。服务器在客户端上执行它的最可能方式是“将“X”合并到一个公共分支中,并希望用户在此分支上执行其他工作,并将其推送回服务器,而不会注意到合并。)

  2. 与#1一样,攻击者选择一个对象ID X来窃取。受害者发送攻击者已经拥有的对象Y,并且攻击者错误地声称拥有X而不是Y,因此受害者将Y作为针对X的增量发送。该增量显示X的区域与攻击者的Y类似。

BUGS

使用—recurse-submodules只能在已检出的子模块中获取新的提交。例如,上游在超级项目的刚刚提取的提交中添加了一个新的子模块,子模块本身无法获取,因此无法在以后检查该子模块而无需再次进行提取。预计将在未来的Git版本中修复。

也可以看看

git-fetch [1]git-merge [1]git-config [1]

GIT

部分 git [1] 套件