使用单个命令获取远程服务器中的所有更改

fetch all changes in remote server using single command

我有不添加远程 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.

之间的区别

这是因为 refspec added when you do a git remote add.

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 要获取的内容。

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

三种模式git fetch

不算 "groups"(这更复杂),git fetch 命令允许的有用语法是以下三个中的一个——但一次只能是一个:

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

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

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

refspecs 确定要获取的内容。稍后我将对此进行详细描述。

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

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

参考规格

Git 的参考规范,我认为,是使用 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>从</em>:<em>到</em>, "source"在左边,"destination"在右边。提取的来源是 "their stuff" 但推送的来源是 "your stuff".

第二个也是更重要的,但是,对于 fetch,如果你只写 one 名字,"destination" 部分默认为空:把获取的no 分支或标签上的内容。对于 push,"destination" 部分默认为一个相当复杂的方法,我不会在这里描述,只是说它永远不会 empty.

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

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

这有两个含义:

  1. 如果您通过参数提供 refspecs,但将它们的目的地留空,fetch 会带入您命名的来源,但只将结果放入 FETCH_HEAD
  2. 如果您 根本 不提供任何参考规范——请记住,这只有在 URL 形式的 git fetch 中才有可能,因为 remote-name 形式从配置文件 1 中获取默认的 refspecs——然后 git fetch 假装你给了它 HEAD,这使得目标为空。这带来了 HEAD 并且与情况 1 一样,将结果仅放入 FETCH_HEAD.

特殊的 HEAD 参考是遥控器上设置的任何 HEAD。对于典型的 "bare" 存储库 HEAD 通常是指向分支 master 的符号引用,因此您使用 URL 的默认值可能会带来他们的 master 但只把它放在你的 FETCH_HEAD 中。但这取决于他们对 HEAD 参考做了什么(当然这是他们的控制权,但是他们喜欢)。


1我不确定当配置文件没有 fetch = 行时会发生什么:git fetch 是否将其视为 "bring over no refs at all",还是将其视为 "I had no refspecs so supply the default HEAD refspec with an empty destination, a la URLs"?