gpt4 book ai didi

git - git pull命令输出消息含义到哪个分支

转载 作者:行者123 更新时间:2023-12-04 15:51:19 30 4
gpt4 key购买 nike

假设远程仓库中有一个远程分支br1签出,而本地仓库中有一个master分支。


命令1:如果我执行“ git pull origin br1:br1”,它将把远程br1拉入本地br1,并显示:

9188a5d..97d4825 br1 -> br1
9188a5d..97d4825 br1 -> origin/br1

命令2:如果我仅执行“ git pull”,它将把远程br1拉入本地master,但仅显示以下内容:

9188a5d..97d4825 br1 -> origin/br1



我希望它也显示类似“ br1 -> master”的内容。为什么不显示呢?

br1 -> br1”是否意味着将远程br1拉入本地br1

br1 -> origin/br1”是什么意思?

更新:在VonC的帮助下,我发现了以下内容:


git pull更新所有跟踪分支。 br1 -> origin/br1表示遥控器上的br1被拉到本地跟踪分支origin/br1中。
git pull origin br1:br1将远程br1拉入本地br1origin/br1。然后,此后的消息意味着相同的更改集也被拉入当前已签出的分支(消息为Updating ...,不显示br1 -> master):

$ git pull origin br1:br1
beb48a4..b344dd1 br1 -> br1
beb48a4..b344dd1 br1 -> origin/br1
Updating cca5a9b..b344dd1
Fast-forward
file2 | 0
file3 | 0
4 files changed, 0 insertions(+), 0 deletions(-)

以前我以为git pull可以加入本地主机。事实并非如此。正是git pull origin br1:br1做到了。


更新2:根据torek的解释,特定的问题是命令git pull origin br1:br1在一系列其他操作之后将远程br1拉入FETCH_HEAD,随后将FETCH_HEAD合并到当前分支中。

最佳答案

警告:长。 TL; DR版本:您正在查看git fetch输出,而git fetch根本不影响您的master,这是影响您git mergegit pullmaster部分。但是,您的git fetch正在更新远程跟踪分支origin/br1,在一种情况下,甚至会更新甚至创建本地分支br1

git pull是一个便捷脚本

始终记住,git pull只是一个方便脚本,可以为您运行另外两个git命令:首先,git pull将您的参数传递给git fetch。完成此操作后,git pull将运行git merge(或,如果有指示,请输入git rebase),但是原始问题中所有引用的操作仅在git fetch中发生。 (“更新”部分的一部分来自git merge,我将在后面介绍。)

如果不提供git pull的远程参数,则pull脚本将从当前分支的配置中提取一个。在这种情况下,其提取的内容显然是origin。因此,如果您在未指定git pull的情况下运行origin,则实际上是在运行git pull origin

如果您没有为git pull提供refspec参数,则pull脚本将从您当前分支的配置中提取一个非常简单的脚本-在这种情况下,您从git config --get branch.master.merge中看到的显然是br1。因此,这意味着如果您运行git pull origin,则实际上是在运行git pull origin br1 .1

同样,所有这些然后都直接传递给git fetch,所以无论您运行git pullgit pull origin还是git pull origin br1,所有这些最终都会调用:

git fetch origin br1


(您也可以手动进行操作,然后会看到上面的内容)。

稍后,我们将转到 git fetch origin br1:br1

可能的误解的背景

让我们再次简要查看您的设置语句:


假设远程仓库中有一个远程分支 br1签出,而本地仓库中有一个 master分支。


当前在远程上签出的分支(如果有)与 fetch几乎无关。 fetch做的第一件事(或第一件事)是连接到遥控器,并要求它提供所有引用及其对应的SHA-1的列表(您可以通过运行 git fetch看到 git ls-remote可以看到的内容) 。遥控器的 HEAD包含在该列表中,这使您可以指示自己的 fetch使用它,但是如果不使用它,您的 fetch只会忽略它(遥控器的 HEAD通常仅用于控制初始 git clone上的默认初始分支)。

但是,本地仓库中的当前分支很重要,原因有两个:


如果您不向 git pull提供额外的参数,它将根据您当前的分支找到它们;和
fetch成功后, git pull运行 git mergegit rebase,它们使用当前分支。


同样,您当前的分支是 master,因此 pull将使用 branch.master.remotebranch.master.merge作为默认的remote和refspec参数。2这就是我们可以从原始输出中推断出它们是 originbr1分别。

git fetch

返回 git fetch,它的作用是与远程git服务器进行一些协商,以找出可用的引用(主要是分支和标签)以及它们对应的SHA-1值。一旦获得了这些信息,它就会查看您要求它带来哪些引用。如果您列出了像 br1这样的特定参考,那将是它带来的参考。

当然,与每个引用一起,它必须带来任何新对象(提交本身及其关联的树和文件,以及根据需要添加任何父提交及其树和文件),以便从中获得所有历史记录。特定点倒退。当然,无论您拥有什么历史,它都可以跳过。3

作为 VonC already noted,git在 git fetch remote refspec上的行为在git 1.8.4及更高版本中已更改。过去,如果您运行 git fetch remote refspec,则refspec会覆盖该git的git配置条目中的规则,但现在它只是从中进行选择。默认情况下,名为 origin的远程服务器的规则集为 +refs/heads/*:refs/remotes/origin/*,因此您的 br1 refspec从此规则集中选择一个项目。



让我们暂停一下,如果仅使用三个参数运行 git fetch会发生什么,如下所示:

$ git fetch origin


在这里,您正在指示本地git连接到远程服务器,找出它所具有的内容,并带来所有分支。这样做的方式(和原因)如上所述:它连接,获取列表,然后查询 git config --get-all remote.origin.fetch .4的输出。这是“ refspecs”的列表,每行 git config --get-all一个。

由于 remote.origin.fetch的标准行(单行)是 +refs/heads/*:refs/remotes/origin/*,因此您的本地git将采用与 refs/heads/*匹配的每个引用名称。也就是说,它将占用 origin上的所有分支,因为分支只是“名称以 refs/heads/开头的引用”。这些分支的作用由该refspec的右侧确定:它将 refs/heads/替换为 refs/remotes/origin/

结果是一个“远程跟踪分支”。如果遥控器具有分支 master,则本地git会将其转换为 origin/master。如果遥控器上有 br1,则本地git会将其翻译为 origin/br1。对于遥控器上的每个分支,您将获得一个(本地)远程跟踪分支,该分支的名称以 origin/ .5开头。



回到 git fetch origin br1的情况,我们现在可以看到发生了什么:本地git带来了 br1,它原来是一个分支,因此其全名是 refs/heads/br1。因此,它与标准 remote.origin.fetch行匹配,并且 refs/heads/br1转换为 refs/remotes/origin/br1,这导致git打印出 origin/br1


9188a5d..97d4825  br1        -> origin/br1



左侧的名称 br1是遥控器上引用的简称,右侧的名称 origin/br1git fetch已更新的引用的简称。

在过去,您可能会看到类似这样的内容,并且仍然可以看到:

* branch            name       -> FETCH_HEAD


这表示 git fetch在远程上找到了一个名为 name的分支(即,引用形式为 refs/heads/name),并将其转移到本地存储库中,并将其放入 FETCH_HEAD中。什么是 FETCH_HEAD?这是一个特殊文件,仅针对 git pull脚本存在。 (它的工作原理与参考非常相似,但是它具有特殊的格式,并且可能包含多个SHA-1。)



现在,我们(终于)准备解决 br1:br1问题。在这里,您要告诉您的本地 git fetch带来引用 br1。它照常执行-调用遥控器,发现 br1确实是 refs/heads/br1,并带走引用和任何需要的对象-但是这次,除了查询 remote.origin.fetch行之外,它还编写了新的SHA -1放入您指定的参考中。

在这种情况下,您指定的 br1没有限定条件:不是 refs/heads/br1,不是 refs/remotes/origin/br1,只是 br1。在这种情况下,git看到它是远程服务器上的 refs/heads/引用,这意味着它是分支。因此git也会在您的末尾添加 refs/heads/,并创建或更新自己的 refs/heads/br1

换句话说,这将创建或更新您的本地分支 br1

另外,git仍然应用 remote.origin.fetch行,该行仍为 +refs/heads/*:refs/remotes/origin/*,因此它仍会更新您的远程跟踪分支 origin/br1(全名 refs/remotes/origin/br1)。这就是为什么您从Command 1获得输出的原因。

git merge

FETCH_HEAD呢?好吧,这是 git pull其余部分返回的位置:在执行 git fetch步骤之后, pull脚本将运行 git mergegit rebase。它合并的内容(或变基为基础)是 git fetch文件中留下的 FETCH_HEAD(带有一些特殊的大写字母和其他注意事项,我在这里不再赘述)。

当当前分支为 master但指示 git pullorigin br1时,正是 git merge步骤使 masterbr1保持最新。更准确地说,合并使您可以在 origin/br1完成时获取最新的 git fetch副本-很可能在 git fetch完成后,其他人进行了 git push更新 br1在您的遥控器上。

如果可能的话,合并是一个“快进”合并,但是我在这里不再赘述。我只是注意到这是可能的,所以做到了;这是更新中的 Fast-forward行。

无论如何,由于当前分支的合并基础和目标提交( master留在 git fetch文件中的原始SHA-1,这也是 FETCH_HEAD的新SHA-1,在某些情况下,也是新的或更新的本地分支 origin/br1的新SHA-1)。

在1.8.4之前的git版本中, br1远程跟踪分支未更新。不过,所有内容仍然可以在 origin/br1文件中使用,而且,即使有什么问题,也比新版gits更加令人困惑,在这里我们可以说,您现在是最新的 FETCH_HEAD,而不必太苛刻和挑剔“ origin/br1,就像您运行 br1时在遥控器上一样”。

那是加号是什么?

敏锐的读者会注意到 git fetch中的 +。此 +refs/heads/*:refs/remotes/origin/*符号表示“强制更新”。通常,在更新分支引用时(任何以 +开头的引用),git均不允许更新,除非它是“快进”标签更新。在refspec中设置force标志会允许该特定更新。在命令行上使用 refs/heads/还允许该更新以及所有其他参考更新。换句话说,加号只是 --force的更具针对性(单个refspec)版本。



1这是一个夸大的说法:有时它使用三个参数 --force

2对于远程位始终为true,但refspec位可能为空, git fetch脚本确定 pull完成后稍后要应用哪个refspec。

3默认情况下, git fetch操作还将带入与其所带入的任何提交ID匹配的所有标记名引用。如果您自己运行 fetch,则可以更改 git fetch处理它们的方式,但是,如果仅让 fetch运行 git pull,则会得到此默认行为。请注意,是由您的本地git做出这些决定:远程git只是将所有内容显示到本地git,然后您的git决定是否向存储库添加标签。

4技术上 git fetch只是调用执行此操作的C代码,而不是实际运行 git fetch。无论如何,如果 git config --get-all有多个配置条目,则 remote.origin.fetch实际上确实适用所有这些条目。但是,它的执行方式有点复杂,在此我将跳过详细内容。

5远程跟踪分支实际上只是名称以 git fetch origin开头的引用,就像本地分支是名称以 refs/remotes/开头的引用一样。这在git中很普遍:您的标记是名称以 refs/heads/开头的引用。 refs/tags脚本使用单个特殊引用 git stash。 Git的“注释”存储在 refs/stash下,您可以发明自己的引用:只需选择一个不同的起始字符串,并希望以后没有其他人会为新的git功能选择相同的字符串。 :-)

关于git - git pull命令输出消息含义到哪个分支,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28337390/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com