【问题标题】:fetch all changes in remote server using single command使用单个命令获取远程服务器中的所有更改
【发布时间】:2015-03-16 12:09:54
【问题描述】:

我有不添加远程git-hub服务器而是直接做fetch的习惯

当我这样做时

git fetch url //does not fetch all the changes from remote
git remote add origin url 
git fetch origin //fetches all the changes from remote

是否有任何命令可以使用单个命令获取远程中的所有更改。 还有 fetch url 和 fetch origin 的区别。

【问题讨论】:

    标签: git github


    【解决方案1】:

    这是因为在您执行 git remote add 时添加了 refspec

    remote.origin.url=git@github.com:<username>/<reponame>
    remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
    

    该 refspec 将指示 git 获取什么以及在哪里获取:

    • 它获取所有heads
    • 将它们放入您的本地克隆仓库remotes/origin/

    (正如我在 this answer 中提到的那样)

    当你直接使用 url 时,本地配置中没有 respec 来指示 Git 获取什么。

    【讨论】:

      【解决方案2】:

      养成使用origingithub 之类的远程名称的习惯可能会好得多,但我自己对此有点疑惑,所以我进行了一些调查。简短的回答是,在没有 refspec 的情况下,git fetch <em>url</em> 会带来他们在HEAD 中的所有内容,并将其丢弃在您的FETCH_HEAD 中(见下文)。

      git fetch 的三种模式

      不包括“组”(这使情况更加复杂),git fetch 命令允许的有用语法是以下三种中的一种,但每次只能使用一种:

      1. git fetch <em>remote</em> [<em>refspecs</em>]
      2. git fetch url [<em>refspecs</em>]
      3. git fetch --multiple <em>remote</em> [<em>remotes</em>]

      方括号表示可选的附加参数。

      remote 只是一个名称,例如 origin,您已将 git 存储在配置文件中。当您第一次克隆存储库时,git 会为您创建名称 origin;对于其他人,您通常希望使用 git remote add <em>name</em> <em>url</em> 添加一个名为 name 的新遥控器。 每个远程都存储一组默认的 fetch refspecs 以及 URL,当您运行 git fetch 时,如果您从命令行中省略它们,这些就是使用的 refspecs。 (如果您提供了至少一个 refspec,则配置的默认值将被忽略,而使用您提供的默认值。)

      refspecs 决定了要获取什么。我稍后会详细描述一下。

      如果您直接指定 URL 而不是远程名称,那么 git 在这里的行为仍然相同:它使用您提供的 refspecs 来确定要获取的内容。 URL 与命名远程的主要区别在于,对于 URL,没有配置文件条目来提供默认的 refspecs 集。这意味着您可能应该至少提供一个 refspec。 但是,如果您不这样做,那么在这种情况下默认的 refspec 就是 HEAD。请参阅下文了解这意味着什么。

      (为了完整起见,最后一种形式,--multiple,只是告诉git fetch所有参数都是远程名称,而不是一个远程名称后跟一些 refspecs。在这种情况下refspecs都像往常一样来自配置文件.换句话说--multiple只是告诉git,例如,当你说git fetch --multiple origin github时,你并不是要从origin获取refspec github,而是要从远程origin,然后也来自远程github。)

      参考规范

      我认为,Git 的 refspec 是使用 git 的文档最少且最令人困惑的方面之一。这是令人惊讶的,因为它们实际上非常简单和优雅,尽管您必须简单地学习和记住一些奇怪的东西。

      refspec 的通常形式只是一对分支或标签名称,例如master:masterv1.2:v1.2。完整形式拼出完整的参考名称,例如refs/heads/masterrefs/tags/v1.2,还包括一个可选的前导加号+(我将在这里忽略);还有一个更缩写的形式,只包含一个分支或标签名称,例如,master

      有点令人困惑的是fetchpush 并不完全对称。

      首先,使用fetch,您将他们的 分支名称放在左侧,您的 名称放在右侧。如果您想将分支master 从远程带到您的分支work,您可以将其写为master:work。但是,使用push,您将您的 分支名称放在左侧,将他们的 名称放在右侧:从您的work 推送到他们的master,你会写work:master。记住这一点的简单方法是它始终是<em>from</em>:<em>to</em>,左边是“源”,右边是“目的地”。提取的来源是“他们的东西”,而推送的来源是“你的东西”。

      第二个更重要的是,对于fetch,如果您只写一个名称,“目标”部分默认为空:将获取的内容放在no 分支或标签。对于push,“目标”部分默认为一个相当复杂的方法,我不会在这里描述,只是说它永远不会为空

      通常,如果你带来一个分支,放置它的最佳位置是远程跟踪分支。例如,如果您从origin 中带入master,则应将结果放入refs/remotes/origin/master(这是origin/master 的完整拼写形式)。同样,如果你带了一个标签,最好的放置它的地方也是一个标签。如果您使用远程名称,git 将为您设置所有这些,您无需做任何特别的事情,您只需 git fetch origin 并将其所有分支复制到您自己的远程跟踪分支,并带有特殊标签为相应的标签做了魔术。

      但是,如果您不想使用远程跟踪分支,则可以使用 git fetch 仍然处理它带来的事情的更老的方式。 git 在 .git 目录中保存了一个名为 FETCH_HEAD 的特殊文件。每次获取,即使只是去一个 URL,都会更新这个文件(通常完全替换它,但是用-a--append,保留旧内容并添加新内容)。无论git fetch 带来什么,它都会写入这个文件。

      这有两个含义:

      1. 如果您通过参数提供 refspec,但将其目的地留空,fetch 会带来您命名的源,但仅将结果放入 FETCH_HEAD
      2. 如果您提供任何参考规范,请记住,这仅适用于git fetch 的纯 URL 形式,因为远程名称形式从以下位置获取默认参考规范配置文件1——然后​​git fetch 假装你给了它HEAD,这使得目的地为空。这带来了HEAD,并且与案例1一样,只将结果放入FETCH_HEAD

      特殊的HEAD 引用是遥控器上设置的HEAD。使用典型的“裸”存储库HEAD 通常是指向分支master 的符号引用,因此您使用URL 的默认设置可能会带来他们的master,但只将它放在您的FETCH_HEAD .但这取决于他们对HEAD 参考所做的处理(当然,这是他们可以随意控制的)。


      1我实际上不确定当配置文件没有 fetch = 行时会发生什么:git fetch 是否将其视为“根本不提供任何参考”,还是将其视为这就像“我没有参考规范,所以提供默认的 HEAD 参考规范,目的地是空的,比如 URL”?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-19
        • 1970-01-01
        • 1970-01-01
        • 2011-08-03
        相关资源
        最近更新 更多