繁体   English   中英

git 获取远程分支,但在本地存储库或工作副本中看不到

[英]git fetch remote branch, but cannot see in local repository or working copy

我当前的分支是 staging_kei20201211,我想从 origin/staging 分支获取最新的代码,我输入以下命令

git fetch origin staging

它说获取输出

1) 然后我 go 到 Visual Studio 查看我的分支 staging_kei20201211 的历史记录,但我看不到 fetch output 中所述的提交 c03c99691,为什么?

  1. fetch output 屏幕的含义是什么? 来自 http://XXXXXX/gitea/elm-ha/CFMS
  • 分支暂存-> FETCH_HEAD c97e1dbb7..c03c99691 暂存-> 原点/暂存

请注意,获取仅更新本地跟踪分支。 在这种情况下,您的 fetch 更新了以下分支:

origin/staging_kei20201211

要更新实际的本地分支staging_kei20201211 ,您需要执行以下附加步骤:

# from staging_kei20201211
git merge origin/staging_kei20201211

更典型的是,您会检查您的本地分支并执行git pull

git checkout staging_kei20201211
git pull origin staging_kei20201211

让我们先从问题 2 开始,因为它对查看问题 1 很有用:

fetch output 屏幕的含义是什么?

 From http://XXXXXX/gitea/elm-ha/CFMS * branch staging -> FETCH_HEAD c97e1dbb7..c03c99691 staging -> origin/staging

上面其实还有更多 output ,其中大部分都以单词remote:为前缀。 remote:前缀文本是来自服务器本身运行的命令的 output。 This led to the server discovering 59 internal Git objects that their Git wanted to send to your Git, for your Git to get everything they have, that you did not have but were asking for, at this time. 然后他们“打包”这些对象,实际上将其进一步压缩到大约 2 KiB 以发送,然后发送; 您的 Git 然后解压缩此数据,并将内部对象放入您的存储库中。

此时,您拥有所有新提交,但您无法在存储库中找到新提交。 新的提交是From http://... ,所以这是From部分。 这些提交是在其他Git 存储库中找到的,通过使用其他 Git 存储库的名称staging 因此,您的 Git 向名为FETCH_HEAD的内部文件写入了您给git fetch的分支名称,即staging ,对应于提交c03c99691 ,它现在存在于您的存储库中(但到目前为止,您仍然没有名称找到它)。

最后一行告诉您 Git 在您的存储库中做了什么,以使您可以找到提交c03c99691 您自己的 Git 更新了您的姓名origin/staging 您的origin/staging用于查找提交c97e1dbb7 现在它找到了提交c03c99691 就是这样:

 c97e1dbb7..c03c99691  staging -> origin/staging

意味着:他们的staging成为您的origin/staging并且您的origin/staging曾经持有c97e1dbb7 ,但现在持有c03c99691 ,与他们的staging相同。

这里的最终结果是您的origin/staging ,它是一个远程跟踪名称而不是分支名称,拥有与他们的分支名称staging相同的提交 hash ID 因此,您可以使用名称origin/staging来查找提交。 您还可以使用原始 hash ID: c03c99691

Git 真的是关于提交

在 Git 中,重要的是提交 每个提交都有一个唯一的编号。 您刚刚从他们那里获得的提交以唯一编号为c03c99691的提交结束 (这实际上是一个缩短的形式:完整的 hash ID 更大更丑。Git 有时会缩短它们,只保留前几个字符,以帮助避免压倒单纯的人类。)这个数字在每个 Z0BCC6350105ADFEZFE57 存储库中都是相同的。 您的存储库使用此编号,他们的存储库也使用此编号。

每个提交本身由两部分组成:

  • 提交包含每个文件的完整快照。 提交中的文件以特殊的、压缩的、只读的、仅 Git 的和重复数据删除的格式存储。 这样一来,当您进行新提交时,您主要是在重新使用上一次提交中的文件,新提交不会占用太多空间。 只有更改的文件需要新的内部 object。 对于所有未更改的文件,它们的内容与其他提交中的文件相同,因此它们可以共享去重部分。

  • 同时,每个提交还包含有关提交本身的一些信息,例如提交人、时间和原因。 在提交中的此信息中,每个提交都包含一个原始 hash ID 的列表,这些 ID 是用于进行提交的任何早期提交的 ID。 通常只有一个这样的 hash ID,我们称之为提交的级。

这个父 hash ID技巧是使 Git 工作的原因。 假设我们有一系列提交,所有提交都在一个简单的行中,没有进行分支和合并。 这个序列中的最后一个提交有一些大而丑陋的 hash ID,但我们只称它为提交H 提交H内部有其父提交的大丑 hash ID; 我们称之为提交G

我们说子提交指向父提交,我们可以画出:

        <-G <-H

您可以看到如何从H中出来一个箭头,向后指向G 当然,还有一个箭头从G中射出。 它向后指向G之前的提交,我们称之为F

... <-F <-G <-H

和以前一样, F也指向后面。 这个向后看的链让我们——或 Git——从最后一次提交开始并找到历史。 存储库中的历史只不过是存储库中的提交。 这就是全部,但这就是所有需要的。 每个提交都向后指向更早的提交。

分行名称和其他名称发生变化; hash ID 保持不变

这是分支名称进入我们图片的地方。 为了找到所有提交,我们需要最后一次提交的 hash ID。 上面,那是提交H 所以我们把最后一次提交的 hash ID 放到一个名字里,比如分支名。 如果分支名称master包含提交G的 hash ID,分支名称staging_kei20201211包含提交H的 hash ID,我们可以这样绘制:

...--F--G   <-- master
         \
          H   <-- staging_kei20201211

在这里,提交H指向之前的提交G 名称master也指向提交G 这意味着通过G的提交在两个分支上,而提交H仅在staging_kei20201211上。

您的存储库中是否是这种情况,我不知道。请注意,我们还使用符号名称GH进行提交;它们的真实名称是丑陋的 hash ID。要查找 hash ID,请使用git rev-parse

git rev-parse master

例如,将告诉您master指向的提交的真实 hash ID。)

考虑到这一点,让我们看看当您向某个分支添加提交时会发生什么。 让我们从git switch mastergit checkout master开始,这样当前分支名称master当前提交为 commit G

...--F--G   <-- master (HEAD)
         \
          H   <-- staging_kei20201211

这张图和上一张的不同之处在于,我们在名字master后面附加了一个特殊的名字HEAD ,告诉我们哪个分支名字是当前分支。 git branch命令现在将以绿色而不是白色打印此名称,正如您在staging_kei20201211中看到的那样。)

我们现在可以创建一个也指向G的新名称,并切换到它,使用:

git switch -C temp-branch

要得到:

...--F--G   <-- master, temp-branch (HEAD)
         \
          H   <-- staging_kei20201211

如果我们现在以通常的方式进行的提交(修改文件, git addgit commit ),我们将获得一个新的提交,具有一个新的、唯一的 Z0800FC577294C34E0B28AD28394359。 这个丑陋的大 hash ID 将是任何其他 Git 存储库中都不存在的 ID(这就是为什么它们必须像它们一样又大又丑),但我们将其称为 commit I ,并像这样绘制它:

          I   <-- temp-branch (HEAD)
         /
...--F--G   <-- master
         \
          H   <-- staging_kei20201211

注意名称temp-branch是如何改变的:它现在指向新的 commit 旧的提交仍然存在,通过G的提交现在在所有三个分支上。 名称已移动,但提交仍保留。 我们刚刚添加了一个新的提交,它现在是分支temp-branch上的最后一个提交。

如果我们检查其他一些分支名称,例如staging_kei20201211 ,并删除名称temp-branch ,我们会得到:

          I   ???
         /
...--F--G   <-- master
         \
          H   <-- staging_kei20201211 (HEAD)

Commit I仍然存在,但是如果你没有在任何地方保存它的 commit hash ID,那就很难找到了。 Git 将保留提交一段时间,以防你想要它回来,但你必须找到它的 hash ID。 如果您不以某种方式将其夺回,Git 最终将完全放弃提交I (如果我们想这样做,这就是我们制作,然后放弃临时提交的方式。)

Git 在hash ID中的fetchpush交易以传输提交

虽然我们按名称查找提交,但实际提交本身由 hash ID 标识。 要查看我们是否已经有一些提交,当我们将两个 Git 相互连接时,它们只是交换原始的 hash ID。 由于这些在每个Git 中都是唯一的,因此一个 Git 可以通过它是否具有具有相同 hash ID 的提交来判断另一个是否具有相同的提交。 如果没有,发送 Git 只是将其发送过来。 所有 Gits 编号都以相同的方式提交, 1因此接收 Git 将使用相同的随机数。


1为完成这项工作,Git 使用了强大的密码学 hash function。 “加密强度”部分对 Git 本身来说不是必需的,但可用于其他目的。 当前的算法 SHA-1 已经不够强大,Git 正在转向新的 hash 算法,但这是一个长期的转换,预见到许多问题; 随着 Git 开始进行转换,不可预见的将会出现。


获取后,接收Git需要有名字

在您的情况下,您运行git fetch到 Git ,其联系人 URL 以名称origin被记住。 您的 Git 调用了 URL 的服务器。 该服务器调用了一个 Git 连接到一个存储库,其中有一个分支名称staging ,其中包含 hash ID c03c99691 为简单起见,我将把这个提交称为K

您的 Git 之前曾与另一个 Git 谈过。 事实上,给定名称origin ,您的 Git 可能是通过将其他 Git 存储库具有的所有提交*复制到您自己的新 Git 存储库来开始的。 所以从那时起,这个提交就被添加到了origin 他们移动了他们的staging名称。 他们可能有:

...--G   <-- master
      \
       J   <-- staging

当您执行原始git clone时,可以在存储库中说:

       H   <-- staging_kei20201211 (HEAD)
      /
...--G   <-- origin/master
      \
       J   <-- staging, origin/staging

(或者可能是具有不同结构的不同图表,但从您的git branch名称和您的git fetch output,我怀疑您有一个origin/master ,并且我知道您有一个origin/staging /master 。) 您的origin/*名称来自您的 Git 复制Git 存储库的分支名称。

无论如何,他们现在有一些新的提交。 我猜他们正好有一个新的提交,而您的git fetch带来了那个:

       H   <-- staging_kei20201211 (HEAD)
      /
...--G   <-- origin/master
      \
       J   <-- staging
        \
         K   <-- origin/staging

如果这张图是准确的,那么J真的是c97e1dbb7K真的是c03c99691

现在回答问题 1

我 go 到 Visual Studio 查看我的分支 staging_kei20201211 的历史记录,但我看不到 fetch output 中所述的提交 c03c99691,为什么?

我不知道或使用 Visual Studio,但一般来说,要让任何 Git 查看器向您显示一些提交,您必须告诉他们最后一次此类提交的原始 hash ID,或者给他们一个允许他们的名称使用 Git 找到最后一个这样的提交。

如您所知,根据定义,名称origin/staging将找到链中以该提交结尾的最后一个提交。 那是因为您的 Git 更新了您的origin/staging以匹配 Git 存储库中的名称staging ,其他 Git 正在查看。

从 bash 风格的命令行:

$ git log origin/staging

会向您展示一些提交,从origin/staging找到的c03c99691开始。 命令:

$ git show origin/staging

会找到提交c03c99691 ,找到它的父级——可能是c97e... ,但如果你刚才从origin获得了两个或更多提交,也许还有其他提交——然后比较两个提交中的快照 对于每个完全相同的文件, git show将不显示任何内容。 对于每个不同的文件, git show会告诉您发生了什么变化。 所有这些都将以提交 c03c99691 中的日志消息为前缀,以及存储在提交c03c99691中的名称和c03c99691地址和日期和时间戳信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM