git fetch 是否拾取已删除的分支?
Does git fetch pick up deleted branches?
用例:
用户 A 在从 master 分支出来的分支 A 上工作;用户 B 创建从 master 分支出来的分支 B 做一些工作并提交,然后删除分支 B。用户 A 可以看到用户 B 的工作(例如 git fetch --all
)。用户 A 从未在分支 B 上工作过。
在这种情况下,分支 B 不会显示给用户 A。
我假设用户A和B在不同的计算机上(A和B)并且master分支存储在服务器上。
第一个
列出已知分支 B 的存储库。
- 用户B在计算机B上使用的
- 服务器上的那个。如果用户 B 在服务器上推送了分支 B。
- 其他? (用户 B 已将分支 B 推送到备份存储库)。
第二个
确保分支已从所有这些存储库中删除。如果没有,A 可以从这里检索分支 B(例如:服务器)。
终于
看看reflog, it provides the recent history of HEAD
(local) and can help user B to retrieve branch B after delete. Some git servers also have some identical feature (like github as explained here).
简短的回答是“否”。
长答案是Mu:所问的问题实际上毫无意义,除非有人做出一些跳跃性的解释(我认为大多数人都会这样做)。原因是 分支无关紧要;你不(完全)获取分支。重要的是 commits,所以正确的问题是 git fetch
是否会获取这些 commits(以及 then 答案通常是“否”)。
我想你也有一个错误的想法:
e.g. git fetch --all
git fetch
的 --all
选项表示 所有遥控器 ,而不是 所有分支 。
这个答案的其余部分是可选的,但我建议它值得一读:当答案变成“是”时你就会发现。
Git 的工作原理
我们从以下内容开始:
一个 Git 存储库的核心是一对数据库:
一个数据库保存提交和其他Git内部对象。这些存储每个文件的每个版本,或多或少。
但是提交(和其他对象)的编号很大,useless-to-humans,seemingly-random 数字(“哈希 ID”或“对象 ID”)。为了使这些东西可供人类使用并因此有用,Git 存储库中的 other 数据库将 names 转换为内部编号。
Git 存储库中的名称包括分支名称,但这些不是唯一的名称。还有标签名称,有趣的东西叫做remote-tracking名称或remote-tracking分支名称,等等。人们(相当错误地)有时将 remote-tracking 名称称为“远程分支名称”,但这是非常误导的。
克隆一个Git存储库的行为意味着给我所有的提交和none分支。 (这在某种程度上可以通过各种选项进行修改,并且不会捕获所有细节,但它是查看克隆的正确起点。)Git 不需要分支。它只需要 提交 和一些 名称来找到它们 .
当我们在本地工作时,在我们从头开始克隆或构建的 Git 存储库中,我们实际上是使用分支名称完成工作的。但是这些分支名称是 在 我们的 存储库 中创建的。它们不在任何其他存储库中!但是,因为人就是人,我们倾向于在两个不同的克隆中使用 相同的 名称:
Bob 有一个存储库。在 Bob 的存储库中,Bob 创建了名为 alpha
和 beta
.
的分支
我克隆了 Bob 的存储库。我不知道他的分支名称:我创建了 我自己的 分支名称。但是因为我打算 with Bob,所以我也调用 my 分支 alpha
和 beta
。
这些是“相同的名称”,最初它们也可能拥有相同的提交 ID 号。但是我的名字是我的,Bob 的名字是Bob 的。他们只有在我们同步他们时才会见面。
当我第一次克隆 Bob 的存储库时,我从他那里得到了他的所有提交和他的分支的 none:我根本没有分支。但是我的Git确实记得他的分支名称。我的 Git 将这些名称 粘贴到 我的存储库中 remote-tracking 名称 的一般类别下。也就是说,我得到的不是 alpha
,而是 bob/alpha
。我得到的不是 beta
,而是 bob/beta
。这些是我Git对Bob分支名称的记忆。
现在,由于我打算 on/with Bob 最近发布的同一个提交,我选择这两个名称之一并让我的 Git create,对我来说,同名分支 : 我现在有一个 alpha
或一个 beta
(但不是两者)。由于任何名称都包含一个内部 Git 对象 ID,因此我的 alpha
或 beta
(无论我选择创建哪个)都包含 相同的 提交哈希ID 为我的 bob/alpha
或 bob/beta
。这是我从 Bob 那里得到的哈希 ID,当我从 Bob 那里得到所有的提交,并将 Bob 的 branch 名字变成我的 remote-tracking个名字.
git fetch
的工作原理
随着时间的推移,Bob 可能会也可能不会进行新的提交。在某些时候,我决定我应该让我的 Git 与 my 克隆一起工作,它有 my 分支(当然还有所有提交,加上我的 remote-tracking 名称),再次调用 Bob 的 Git,并让 Bob 的 Git 连接到 Bob 的存储库。
此时,Bob 拥有他拥有的任何分支。他的 Git(他的软件,运行ning 在他的存储库中)将这些分支名称列出到我的 Git(我的软件,运行ning 在我的存储库中)。这些带有提交哈希 ID:提交对象的那些丑陋的大 random-looking 数字。
我的 Git 检查我是否有这些提交。如果我这样做,太好了!如果没有,我的 Git 会向 Bob 的 Git 询问这些提交,这会导致整个对话 运行 以便我的 Git 可以找到 all new 提交 Bob 有而我没有。我的 Git 下载 所有 这些提交,现在我拥有 Bob 拥有的所有提交,就像我第一次克隆时一样。最后,现在我有了 Bob 的所有提交——也许还有我自己的,在我的分支上——我的 Git 更新了我的 remote-tracking 名称以记住 Bob 的分支名称和提交。
请注意,这对我的任何分支都没有影响。 但是,我会更新我的 remote-tracking 名称——如果 Bob 创建了一个 new 分支名称,而我的 Git 在这个 git fetch
期间看到了它,我的 Git 将创建一个 new remote-tracking 名称与之搭配。如果我设置 fetch.prune
或使用 -p
,并且 Bob 删除了 他的一些分支名称,我的 Git 将 删除 对应的 remote-tracking 名称也是。所以 git fetch
更新,对我来说, remote-tracking 我打电话给 Git 的名字。
这里的关键问题是:我调用了什么Git,Git有什么名称和提交?我在这里说我调用了 Bob 的 Git,其中包含 Bob 的分支名称和 Bob 的所有提交,因此我们可以回答这些问题并查看我现在有哪些 remote-tracking 名称,以及这些名称包含哪些对象哈希 ID。
引入“分叉”and/or“中央存储库”
在上面,我一直直接使用Bob的电脑。当我 运行 git fetch
时,我获得 Bob 计算机的 ssh 访问权限(或其他),以某种方式登录到它,以便我可以 运行 Git那边指挥。这在某些 Linux-server-type 环境中很好,例如公司 Git 设置。但是许多地方不想这样工作,and/or 想要一个单一的“真实来源”集中式存储库,无论是托管在 in-company 还是在 GitHub 或其他什么地方。
所以现在我不会 访问 Bob 的存储库,在 Bob 的计算机上。取而代之的是,在某处有一个中央仓库,至少在最初只有 一个分支 ,名为 master
。 Bob 将克隆该集中式存储库并获得 origin/master
并使用它在 Bob 的 Git、master
中创建。然后 Bob 使用他的 master
创建一个新的分支名称 alpha
.
当我连接到中央存储库时,我的 Git 生成了 我的 克隆,它具有所有提交但没有分支名称和一个 remote-tracking 名称origin/master
。我(或者我的 Git 无论如何)使用我的 origin/master
创建一个名为 master
的分支,然后我用它来创建我的分支名称 beta
.
当我 运行 git fetch
时,我的 Git 转到 origin
。 Bob 没有告诉 origin
上的 Git 创建 任何 新分支名称。所以我根本不会看到 任何 Bob 的 分支名称,因为我从不直接与 Bob 的 Git 交谈,我赢了'看到 Bob 的任何分支名称被复制到 origin
因为他还没有这样做。
当 Bob 最终 运行 成为 git push
时,他做了:
git push -u origin alpha
这使得他的 Git 在 origin
调用 Git 并向它提供 - origin
Git - Bob 的任何提交在 origin
还没有的 alpha
上。1 他们接受这些提交,然后 Bob 要求来源 Git 在来源上创建,一个新分支名称,alpha
。如果 origin Git 服从这个请求——这取决于 origin Git 和任何人可能已经安装和调整的控制旋钮(基本 Git 这里没有太多,但是大多数托管站点do)—然后 现在 原点 Git 有一个名为 alpha
.
的分支
我的 Git,在 origin
调用 Git,现在可以看到 alpha
,并创建我的 origin/alpha
remote-tracking 名字(在获得这五个或其他任何东西之后,new-to-my-Git 提交)。那是我的remote-tracking名字,origin
的分支名字,但我只能看到它因为 Bob说服 origin
创建它。
如果 Bob 决定制作一个 GitHub-style fork,他所做的就是制作另一个克隆,但这次是托管在 GitHub 上。 Bob 的克隆是 另一个单独的 Git 存储库 并且这个克隆有自己的分支名称。这个克隆有一个或两个特殊的事情:当 GitHub 创建它时,GitHub 确实 复制所有分支,所以最初那个克隆有所有与我将使用的 origin
克隆相同的分支。此外,当 Bob 在 Bob 的 GitHub 分支上创建新的提交和分支名称时,Bob 可以向 origin
Git。 (这就是 GitHub 作为 add-ons 提供的所有内容,让您想使用 GitHub 而不是 self-hosting。)
在所有这些情况下,直到Bob 以某种方式在 origin
Git 上创建了一个新分支,我看不到 Bob 的 提交 。我只能看到 origin
上的 分支名称 ,它们将成为我的 remote-tracking 名称;我只能在 Bob 以某种方式将 交给 和 origin
Git 之后得到 Bob 的提交,并在 on 上命名origin
Git 以便我——或者我的 Git——可以找到他们的提交哈希 ID 号。
1这个措辞涵盖了 master
上的所有提交现在都在 两个分支 上的事实。因此 origin
处的 Git 有大量在 alpha
上的提交;只是 Bob 有五个 更多 次提交,或者 Bob 提交的次数。
遥控器
在上面的过程中,我的Git一直正好有一个remote。
当我使用直接进入 Bob 的计算机的示例时——这让我可以随时看到 Bob 的所有分支——我为这个遥控器使用了名称 bob
,所以我的 remote-tracking 个名字 分别是 bob/alpha
和 bob/beta
.
当我使用 GitHub 作为示例时,我使用名称 origin
作为遥控器,所以我的 remote-tracking 名称是 origin/master
,最终(一旦 Bob 也在那里创建了一个 alpha
)origin/alpha
.
A remote 主要是 URL 的简称。我可能用于 Bob 计算机的 URL 可能是 ssh://bob.company.com/path/to/repo.git
。我可能用于 GitHub 的 URL 可能是 ssh://git@github.com/company/repo.git
.
默认情况下,git clone
命令将使您的新克隆具有作为其(一个,单个)远程的远程名称 origin
。此名称将存储您给 的 URL 到 git clone
,以便稍后,git fetch origin
将返回相同的 URL 和从他们那里得到任何新的提交。
但是,您可以拥有多个遥控器。这里唯一的限制是每个人都必须有一个唯一的名字。因此,如果我 可以直接访问 Bob 的计算机,我可以 添加 到我的克隆,其中 origin
指的是 GitHub clone ... 和 now 我 可以 直接访问 Bob 的存储库,因此可以看到 Bob 的分支,就像我的 bob/*
remote-tracking 个名字。所以现在答案更改,从不,我看不到 Bob 的分支 到 是,我可以看到 Bob 的分支。我会有 origin/master
,还有 bob/alpha
(还有 bob/master
,除非他删除了他的名字 master
)。
既然我多了一个远程,运行宁git fetch --all
就有意义了。之前,只有一个名为 origin
的遥控器,git fetch --all
意味着 从所有遥控器中获取 ,这意味着 从 origin
中获取,这就是 git fetch
没有 --all
的意思:只有一个遥控器,所以 遥控器就是我们从中获取的遥控器。
使用 两个 遥控器,但是 git fetch
没有额外的限定符意味着 从 一些 遥控器获取。哪一个? The git fetch
documentation这里不是模型的清晰度,目前的答案是:
- 如果我在分支 B 并且 B 有一个 remote 的配置 R,这是
git fetch
使用的;
- 否则,
git fetch
将返回到名称 origin
。
(这可能有一天会改变。)
如果我给 git fetch
起一个像 origin
或 bob
这样的名字,那就是它将从中获取的远程,还有更多选项,例如“远程组”和课程 --all
。使用 --all
将 git fetch
定向到 所有 遥控器上的 运行 git fetch
,一次一个。2
因此:--all
只有在您定义了两个或多个遥控器时才 有用。如果您设置了对 Bob 的存储库的远程访问,您可以看到 Bob 的分支。这当然需要您 访问 到 Bob 的机器,或者 Bob 在 GitHub 上的分支,或其他任何东西。
2理想情况下 Git 应该 运行 多个并行提取,但目前没有。
结论
最后,这里真正的关键是提交。我们通过它们的哈希 ID 得到 commits。我们 通过名称找到 那些哈希 ID——分支名称、标签名称、remote-tracking 名称,任何名称。 git fetch
命令可以访问其他一些 Git(软件+存储库)。默认情况下,它使用 它们的 分支名称(及其标签名称,取决于 --tags
和其他提取选项)来查找要获取的提交,获取这些提交,然后创建或更新 our 存储库中的名称,但使用标准设置,我们在存储库中为他们的 branch 获取的名称是我们的 remote-tracking 名称。
我们唯一能看到的名字是他们提供给我们的名字,他们只能提供给我们他们拥有的名字。因此,如果“他们的Git”是某处的中央存储库,并且 Bob 创建Bob 的克隆中的牧场并在那里进行提交,但从不将名称 或 提交到集中式存储库,集中式存储库首先没有任何东西可以给我们。
用例:
用户 A 在从 master 分支出来的分支 A 上工作;用户 B 创建从 master 分支出来的分支 B 做一些工作并提交,然后删除分支 B。用户 A 可以看到用户 B 的工作(例如 git fetch --all
)。用户 A 从未在分支 B 上工作过。
在这种情况下,分支 B 不会显示给用户 A。
我假设用户A和B在不同的计算机上(A和B)并且master分支存储在服务器上。
第一个
列出已知分支 B 的存储库。
- 用户B在计算机B上使用的
- 服务器上的那个。如果用户 B 在服务器上推送了分支 B。
- 其他? (用户 B 已将分支 B 推送到备份存储库)。
第二个
确保分支已从所有这些存储库中删除。如果没有,A 可以从这里检索分支 B(例如:服务器)。
终于
看看reflog, it provides the recent history of HEAD
(local) and can help user B to retrieve branch B after delete. Some git servers also have some identical feature (like github as explained here).
简短的回答是“否”。
长答案是Mu:所问的问题实际上毫无意义,除非有人做出一些跳跃性的解释(我认为大多数人都会这样做)。原因是 分支无关紧要;你不(完全)获取分支。重要的是 commits,所以正确的问题是 git fetch
是否会获取这些 commits(以及 then 答案通常是“否”)。
我想你也有一个错误的想法:
e.g.
git fetch --all
git fetch
的 --all
选项表示 所有遥控器 ,而不是 所有分支 。
这个答案的其余部分是可选的,但我建议它值得一读:当答案变成“是”时你就会发现。
Git 的工作原理
我们从以下内容开始:
一个 Git 存储库的核心是一对数据库:
一个数据库保存提交和其他Git内部对象。这些存储每个文件的每个版本,或多或少。
但是提交(和其他对象)的编号很大,useless-to-humans,seemingly-random 数字(“哈希 ID”或“对象 ID”)。为了使这些东西可供人类使用并因此有用,Git 存储库中的 other 数据库将 names 转换为内部编号。
Git 存储库中的名称包括分支名称,但这些不是唯一的名称。还有标签名称,有趣的东西叫做remote-tracking名称或remote-tracking分支名称,等等。人们(相当错误地)有时将 remote-tracking 名称称为“远程分支名称”,但这是非常误导的。
克隆一个Git存储库的行为意味着给我所有的提交和none分支。 (这在某种程度上可以通过各种选项进行修改,并且不会捕获所有细节,但它是查看克隆的正确起点。)Git 不需要分支。它只需要 提交 和一些 名称来找到它们 .
当我们在本地工作时,在我们从头开始克隆或构建的 Git 存储库中,我们实际上是使用分支名称完成工作的。但是这些分支名称是 在 我们的 存储库 中创建的。它们不在任何其他存储库中!但是,因为人就是人,我们倾向于在两个不同的克隆中使用 相同的 名称:
Bob 有一个存储库。在 Bob 的存储库中,Bob 创建了名为
的分支alpha
和beta
.我克隆了 Bob 的存储库。我不知道他的分支名称:我创建了 我自己的 分支名称。但是因为我打算 with Bob,所以我也调用 my 分支
alpha
和beta
。
这些是“相同的名称”,最初它们也可能拥有相同的提交 ID 号。但是我的名字是我的,Bob 的名字是Bob 的。他们只有在我们同步他们时才会见面。
当我第一次克隆 Bob 的存储库时,我从他那里得到了他的所有提交和他的分支的 none:我根本没有分支。但是我的Git确实记得他的分支名称。我的 Git 将这些名称 粘贴到 我的存储库中 remote-tracking 名称 的一般类别下。也就是说,我得到的不是 alpha
,而是 bob/alpha
。我得到的不是 beta
,而是 bob/beta
。这些是我Git对Bob分支名称的记忆。
现在,由于我打算 on/with Bob 最近发布的同一个提交,我选择这两个名称之一并让我的 Git create,对我来说,同名分支 : 我现在有一个 alpha
或一个 beta
(但不是两者)。由于任何名称都包含一个内部 Git 对象 ID,因此我的 alpha
或 beta
(无论我选择创建哪个)都包含 相同的 提交哈希ID 为我的 bob/alpha
或 bob/beta
。这是我从 Bob 那里得到的哈希 ID,当我从 Bob 那里得到所有的提交,并将 Bob 的 branch 名字变成我的 remote-tracking个名字.
git fetch
的工作原理
随着时间的推移,Bob 可能会也可能不会进行新的提交。在某些时候,我决定我应该让我的 Git 与 my 克隆一起工作,它有 my 分支(当然还有所有提交,加上我的 remote-tracking 名称),再次调用 Bob 的 Git,并让 Bob 的 Git 连接到 Bob 的存储库。
此时,Bob 拥有他拥有的任何分支。他的 Git(他的软件,运行ning 在他的存储库中)将这些分支名称列出到我的 Git(我的软件,运行ning 在我的存储库中)。这些带有提交哈希 ID:提交对象的那些丑陋的大 random-looking 数字。
我的 Git 检查我是否有这些提交。如果我这样做,太好了!如果没有,我的 Git 会向 Bob 的 Git 询问这些提交,这会导致整个对话 运行 以便我的 Git 可以找到 all new 提交 Bob 有而我没有。我的 Git 下载 所有 这些提交,现在我拥有 Bob 拥有的所有提交,就像我第一次克隆时一样。最后,现在我有了 Bob 的所有提交——也许还有我自己的,在我的分支上——我的 Git 更新了我的 remote-tracking 名称以记住 Bob 的分支名称和提交。
请注意,这对我的任何分支都没有影响。 但是,我会更新我的 remote-tracking 名称——如果 Bob 创建了一个 new 分支名称,而我的 Git 在这个 git fetch
期间看到了它,我的 Git 将创建一个 new remote-tracking 名称与之搭配。如果我设置 fetch.prune
或使用 -p
,并且 Bob 删除了 他的一些分支名称,我的 Git 将 删除 对应的 remote-tracking 名称也是。所以 git fetch
更新,对我来说, remote-tracking 我打电话给 Git 的名字。
这里的关键问题是:我调用了什么Git,Git有什么名称和提交?我在这里说我调用了 Bob 的 Git,其中包含 Bob 的分支名称和 Bob 的所有提交,因此我们可以回答这些问题并查看我现在有哪些 remote-tracking 名称,以及这些名称包含哪些对象哈希 ID。
引入“分叉”and/or“中央存储库”
在上面,我一直直接使用Bob的电脑。当我 运行 git fetch
时,我获得 Bob 计算机的 ssh 访问权限(或其他),以某种方式登录到它,以便我可以 运行 Git那边指挥。这在某些 Linux-server-type 环境中很好,例如公司 Git 设置。但是许多地方不想这样工作,and/or 想要一个单一的“真实来源”集中式存储库,无论是托管在 in-company 还是在 GitHub 或其他什么地方。
所以现在我不会 访问 Bob 的存储库,在 Bob 的计算机上。取而代之的是,在某处有一个中央仓库,至少在最初只有 一个分支 ,名为 master
。 Bob 将克隆该集中式存储库并获得 origin/master
并使用它在 Bob 的 Git、master
中创建。然后 Bob 使用他的 master
创建一个新的分支名称 alpha
.
当我连接到中央存储库时,我的 Git 生成了 我的 克隆,它具有所有提交但没有分支名称和一个 remote-tracking 名称origin/master
。我(或者我的 Git 无论如何)使用我的 origin/master
创建一个名为 master
的分支,然后我用它来创建我的分支名称 beta
.
当我 运行 git fetch
时,我的 Git 转到 origin
。 Bob 没有告诉 origin
上的 Git 创建 任何 新分支名称。所以我根本不会看到 任何 Bob 的 分支名称,因为我从不直接与 Bob 的 Git 交谈,我赢了'看到 Bob 的任何分支名称被复制到 origin
因为他还没有这样做。
当 Bob 最终 运行 成为 git push
时,他做了:
git push -u origin alpha
这使得他的 Git 在 origin
调用 Git 并向它提供 - origin
Git - Bob 的任何提交在 origin
还没有的 alpha
上。1 他们接受这些提交,然后 Bob 要求来源 Git 在来源上创建,一个新分支名称,alpha
。如果 origin Git 服从这个请求——这取决于 origin Git 和任何人可能已经安装和调整的控制旋钮(基本 Git 这里没有太多,但是大多数托管站点do)—然后 现在 原点 Git 有一个名为 alpha
.
我的 Git,在 origin
调用 Git,现在可以看到 alpha
,并创建我的 origin/alpha
remote-tracking 名字(在获得这五个或其他任何东西之后,new-to-my-Git 提交)。那是我的remote-tracking名字,origin
的分支名字,但我只能看到它因为 Bob说服 origin
创建它。
如果 Bob 决定制作一个 GitHub-style fork,他所做的就是制作另一个克隆,但这次是托管在 GitHub 上。 Bob 的克隆是 另一个单独的 Git 存储库 并且这个克隆有自己的分支名称。这个克隆有一个或两个特殊的事情:当 GitHub 创建它时,GitHub 确实 复制所有分支,所以最初那个克隆有所有与我将使用的 origin
克隆相同的分支。此外,当 Bob 在 Bob 的 GitHub 分支上创建新的提交和分支名称时,Bob 可以向 origin
Git。 (这就是 GitHub 作为 add-ons 提供的所有内容,让您想使用 GitHub 而不是 self-hosting。)
在所有这些情况下,直到Bob 以某种方式在 origin
Git 上创建了一个新分支,我看不到 Bob 的 提交 。我只能看到 origin
上的 分支名称 ,它们将成为我的 remote-tracking 名称;我只能在 Bob 以某种方式将 交给 和 origin
Git 之后得到 Bob 的提交,并在 on 上命名origin
Git 以便我——或者我的 Git——可以找到他们的提交哈希 ID 号。
1这个措辞涵盖了 master
上的所有提交现在都在 两个分支 上的事实。因此 origin
处的 Git 有大量在 alpha
上的提交;只是 Bob 有五个 更多 次提交,或者 Bob 提交的次数。
遥控器
在上面的过程中,我的Git一直正好有一个remote。
当我使用直接进入 Bob 的计算机的示例时——这让我可以随时看到 Bob 的所有分支——我为这个遥控器使用了名称 bob
,所以我的 remote-tracking 个名字 分别是 bob/alpha
和 bob/beta
.
当我使用 GitHub 作为示例时,我使用名称 origin
作为遥控器,所以我的 remote-tracking 名称是 origin/master
,最终(一旦 Bob 也在那里创建了一个 alpha
)origin/alpha
.
A remote 主要是 URL 的简称。我可能用于 Bob 计算机的 URL 可能是 ssh://bob.company.com/path/to/repo.git
。我可能用于 GitHub 的 URL 可能是 ssh://git@github.com/company/repo.git
.
默认情况下,git clone
命令将使您的新克隆具有作为其(一个,单个)远程的远程名称 origin
。此名称将存储您给 的 URL 到 git clone
,以便稍后,git fetch origin
将返回相同的 URL 和从他们那里得到任何新的提交。
但是,您可以拥有多个遥控器。这里唯一的限制是每个人都必须有一个唯一的名字。因此,如果我 可以直接访问 Bob 的计算机,我可以 添加 到我的克隆,其中 origin
指的是 GitHub clone ... 和 now 我 可以 直接访问 Bob 的存储库,因此可以看到 Bob 的分支,就像我的 bob/*
remote-tracking 个名字。所以现在答案更改,从不,我看不到 Bob 的分支 到 是,我可以看到 Bob 的分支。我会有 origin/master
,还有 bob/alpha
(还有 bob/master
,除非他删除了他的名字 master
)。
既然我多了一个远程,运行宁git fetch --all
就有意义了。之前,只有一个名为 origin
的遥控器,git fetch --all
意味着 从所有遥控器中获取 ,这意味着 从 origin
中获取,这就是 git fetch
没有 --all
的意思:只有一个遥控器,所以 遥控器就是我们从中获取的遥控器。
使用 两个 遥控器,但是 git fetch
没有额外的限定符意味着 从 一些 遥控器获取。哪一个? The git fetch
documentation这里不是模型的清晰度,目前的答案是:
- 如果我在分支 B 并且 B 有一个 remote 的配置 R,这是
git fetch
使用的; - 否则,
git fetch
将返回到名称origin
。
(这可能有一天会改变。)
如果我给 git fetch
起一个像 origin
或 bob
这样的名字,那就是它将从中获取的远程,还有更多选项,例如“远程组”和课程 --all
。使用 --all
将 git fetch
定向到 所有 遥控器上的 运行 git fetch
,一次一个。2
因此:--all
只有在您定义了两个或多个遥控器时才 有用。如果您设置了对 Bob 的存储库的远程访问,您可以看到 Bob 的分支。这当然需要您 访问 到 Bob 的机器,或者 Bob 在 GitHub 上的分支,或其他任何东西。
2理想情况下 Git 应该 运行 多个并行提取,但目前没有。
结论
最后,这里真正的关键是提交。我们通过它们的哈希 ID 得到 commits。我们 通过名称找到 那些哈希 ID——分支名称、标签名称、remote-tracking 名称,任何名称。 git fetch
命令可以访问其他一些 Git(软件+存储库)。默认情况下,它使用 它们的 分支名称(及其标签名称,取决于 --tags
和其他提取选项)来查找要获取的提交,获取这些提交,然后创建或更新 our 存储库中的名称,但使用标准设置,我们在存储库中为他们的 branch 获取的名称是我们的 remote-tracking 名称。
我们唯一能看到的名字是他们提供给我们的名字,他们只能提供给我们他们拥有的名字。因此,如果“他们的Git”是某处的中央存储库,并且 Bob 创建Bob 的克隆中的牧场并在那里进行提交,但从不将名称 或 提交到集中式存储库,集中式存储库首先没有任何东西可以给我们。