git fetch和git fetch源主机之间的差异

git fetch和git fetch源主机之间的差异,git,git-merge,git-fetch,Git,Git Merge,Git Fetch,我是,我想知道这两者之间是否有区别 git fetch 及 我在GitHub上没有指向我的远程存储库的任何其他分支和原点 当我这样做时: git fetch origin master remote: Counting objects: 4, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 1), reused 0 (delta 0) Unpacking objects: 100% (3/3

我是,我想知道这两者之间是否有区别

git fetch

我在GitHub上没有指向我的
远程存储库的任何其他分支和原点

当我这样做时:

git fetch origin master
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From github.com:XXXXXXXXXXXXXXX
 * branch            master     -> FETCH_HEAD
但只是:

git fetch
From github.com:XXXXXXXXXXXXXXX
   531d466..aaf6df0  master     -> origin/master
请注意,master指向不同的事物;在一种情况下,
FETCH_HEAD
,在另一种情况下,
origin/master
? 它们不同吗

这里是“TL;DR”版本(它掩盖了许多特殊情况):
git fetch
总是更新
fetch\u HEAD
,在各种情况下都有多行。它有时会更新“远程分支”,即全名以
refs/remotes/
开头的refs。其余的大部分是关于“有时”的,这取决于给定给
git fetch
的参数数量和git版本


我有机会测试一下。让我们区分三种情况,所有这些情况都假设运行
git fetch
,而不需要像
-a
甚至
-all
这样的额外选项。让我们也排除
git fetch
更奇怪的变体,比如直接使用URL,或者使用
代替
条目,或者
.git/remotes
.git/branchs
中列出的文件。(我承认我只是在猜测,但我认为这些都是在
[remote“name”]
条目进入git配置文件之前的几天遗留下来的。编辑,2019:结果证明是正确的。)

  • git fetch
    ,没有其他参数

    Git确定您当前的分支(通常通过读取
    HEAD
    ,但您当然可以通过
    Git分支
    Git状态查看它是什么)。然后,它将查找该分支的配置条目,该分支将其命名为
    remote
    。例如,假设您在分支
    dummy
    上,并且
    .git/config
    具有(以及其他条目):

    在这种情况下,
    git-fetch
    相当于
    git-fetch-remote-X
    。在这一点之后,这相当于情况2,即:

  • git fetch remote
    (除此之外没有其他参数)

    Git这次不会查看您当前的分支。要使用的遥控器是命令行中给定的遥控器。它确实为给定的远程服务器查找配置部分。假设您正在使用
    remote-X
    :在本例中,它将查找:

    [remote "remote-X"]
        url = ...
    
    如果该部分不存在,或者没有
    url=
    条目,则会出现一个错误:
    fatal:“remote-X”似乎不是git存储库
    。否则,它将给出url,并且
    git fetch
    将尝试连接到该存储库。假设它能连接

    通常,至少还有一个配置条目,可能更多,如下所示:

        fetch = +refs/heads/*:refs/remotes/remote-X/*
    
    (遥控器的名称在此硬编码)。假设有

    接下来,
    git fetch
    询问远程服务器它有哪些引用(大多数情况下是分支和标记,虽然您可以获取所有引用,但大多数人只关心分支和标记)。您可以使用
    git ls remote-X
    自己做同样的事情,它会泄漏出如下内容:

    676699a0e0cdfd97521f3524c763222f1c30a094        HEAD
    222c4dd303570d096f0346c3cd1dff6ea2c84f83        refs/heads/branch
    676699a0e0cdfd97521f3524c763222f1c30a094        refs/heads/master
    
       22b38d1..676699a  master     -> remote-X/master
    
    HEAD
    ref的处理方式并不完全一致(我看到它的行为很奇怪),但通常在这里它会被删除。2根据
    fetch=
    refspec重命名和更新剩余的分支。(如果存在多个
    fetch=
    refspec,则会根据所有这些规范对它们进行重命名和更新。例如,这主要用于将
    refs/notes/
    带过来或在
    refs/rtags/
    下创建自己的“远程标记”名称空间。)

    在这种情况下,fetch将带来两个分支
    branch
    master
    所需的任何对象,并根据需要更新(本地)“远程分支”名称
    refs/remotes/remote-X/branch
    refs/remotes/remote-X/master
    。对于每个更新的文件,
    fetch
    打印一行,如下所示:

    676699a0e0cdfd97521f3524c763222f1c30a094        HEAD
    222c4dd303570d096f0346c3cd1dff6ea2c84f83        refs/heads/branch
    676699a0e0cdfd97521f3524c763222f1c30a094        refs/heads/master
    
       22b38d1..676699a  master     -> remote-X/master
    
    如果
    fetch=
    行丢失
    ,您会得到完全不同的结果。输出将为:

     * branch            HEAD       -> FETCH_HEAD
    
    在本例中,就好像(缺失的)
    fetch=
    行在那里并且包含
    fetch=HEAD

  • git fetch remote refspec
    refspec
    部分实际上是一个或多个refspec,如下所述)

    这与案例2类似,只是这一次,“refspec”是在命令行上提供的,而不是从远程服务器的
    fetch=
    配置条目提供的。但是,这里的获取行为非常不同


  • 在这种情况下,让我们暂停片刻,正确地描述refspec。(refspec也适用于
    git push
    ,但是,与git一样,实现细节泄漏,并且在那里的工作方式略有不同。)refspec有一个可选的前导加号(
    +
    ),我在这里忽略它;3然后是两部分,用冒号隔开(
    )。两者通常只是一个分支名称,但对于分支名称,您可以(并且
    fetch=
    行可以)拼写出“完整”的ref名称,
    refs/heads/branch

    对于获取操作,左侧的名称是远程设备本身的名称(例如,如
    gitlsremote
    所示)。右侧的名称是要在本地git存储库中存储/更新的名称。作为一种特殊情况,您可以在斜杠后面加一个星号(
    *
    )作为最后一个组件,如
    refs/heads/*
    ,在这种情况下,左侧匹配的零件在右侧被替换。因此,
    refs/heads/*:refs/remotes/remote-X/*
    是导致
    refs/heads/master
    (如远程上所示,带有
    git ls remote
    )变为
    refs/remotes/remote-X/master
    (如本地存储库中所示,以较短的形式,位于
    ->
    git fetch
    的右侧)

    如果您没有输入
    676699a0e0cdfd97521f3524c763222f1c30a094        branch 'master' of ...
    222c4dd303570d096f0346c3cd1dff6ea2c84f83        branch 'branch' of ...
    
    676699a0e0cdfd97521f3524c763222f1c30a094 not-for-merge branch ...
    
    f07cf14302eab6ca614612591e55f7340708a61b not-for-merge 'refs/notes/commits' ...
    
       22b38d1..676699a  master     -> remote-X/master
    
     * branch            master     -> FETCH_HEAD
     * branch            branch     -> FETCH_HEAD
       22b38d1..676699a  master     -> remote-X/master