[英]"Forced update" shown after git pull
在我的存储库中执行git pull
后,它显示
6cca7ee...32eb5b2 bug/12 -> origin/bug/12 (forced update)
以前,我从父分支parent/1.2.3
创建了bug/12
分支,对代码进行了更改,并将bug/12
分支合并到了parent/1.2.3
分支并完成了bug/12 branch
。 但是由于某些问题,我需要再次重新打开 bug 12,因此我再次从parent/1.2.3
创建了一个bug/12
分支,并进行了代码更改并将更改推送到bug/12
分支。 但是现在当我拉动parent/1.2.3
分支时,它显示我强制更新。
因此,如果我将新创建的bug/12
分支合并到parent/1.2.3
分支中,它会产生任何问题还是会删除强制更新?
这种“强制更新”的事情可能会非常令人困惑,但您已经提出了一个重要的问题。
是否有任何实际的问题就在这里,我怀疑有isn't,取决于你是什么意思时,你说:
...并完成了
bug/12 branch
。
Git 没有一个叫做完成的概念。 因此,您导致在哪些存储库中发生的实际 Git 操作并不明显。
如果只有一个存储库,并且它有各种分支名称,例如bug/12
并且您执行了以下操作:
git checkout master
git merge bug/12
git branch -d bug/12
(这会将bug/12
尖端的提交合并到master
,然后删除分支名称bug/12
)这种问题永远不会出现:删除了名称,它不再存在。
但不只有一个存储库。 你:
bug/12
bug/12
bug/12
,所以你的 Git 在你的存储库中创建了一个origin/bug/12
来记住他们的bug/12
现在,在这一切之后,我怀疑你所做的——你所说的“完成的bug/12 branch
”——是你在使用 GitHub 或 Bitbucket 或 GitLab 或类似的东西,你进入了他们的网络界面并使用了各种小按钮将bug/12
合并到他们存储库中的master
,然后删除他们的bug/12
name 。 这与上面显示的三个假设命令非常相似,除了 `git merge bug/12 可以执行快进操作而不是真正的合并,而 GitHub合并拉取请求按钮永远不会执行快进操作。
但我不知道这就是你所做的。 我只是怀疑而已。
假设这就是您所做的,您可能会继续从您自己的存储库中手动删除分支名称bug/12
:
git branch -D bug/12
从那时起,您可能已经运行了git fetch
(或者以一种可以解决问题的方式运行git pull
运行git fetch
),但您可能没有将fetch.prune
设置为true
。 当您运行git fetch
,您的 Git 会在origin
调用 Git 并让它们列出它们的分支名称。 他们此时没有bug/12
分支名称,但是您的 Git 更早创建了您自己的origin/bug/12
,当时他们确实有他们的bug/12
分支名称。 因此,您的 Git 不会对您自己的origin/bug/12
名称执行任何操作:此名称没有新值,但您没有指示您的 Git删除不再具有其他名称的origin/*
名称。
这意味着就您的 Git 而言, origin/bug/12
仍在记住另一个 Git 存储库中的有效bug/12
名称,即使不再有这样的名称。 如果您将fetch.prune
设置为true
或运行git fetch --prune
,您的 Git 将删除此origin/bug/12
。 所以在这一点上,你的origin/bug/12
是一个陈旧的 name 。 (Git 没有定义这个术语——它没有被称为陈旧名称的概念——但这对于这种名称来说似乎是一个很好的术语。)
同样,所有这些都是从事实中推断出来的,实际上并不存在证据。 真的是这样吗? 我不知道:你告诉我的还不够多。
现在,假设以上所有内容都是正确的,您自己的origin/bug/12
还记得前段时间在origin
记住的bug/12
。 那是在您单击合并或变基和合并或挤压和合并Web 浏览器单击按钮之前。 在这一点上,我必须至少再做一个假设:您使用的按钮不是纯粹的合并,而是rebase 和 merge或squash 和 merge 。
让我们画出 rebase-and-merge 或 squash-and-merge 操作之前的情况。 在 GitHub 上的 Git 存储库中(此时我将假设为 GitHub),您有一系列提交,每个提交都以某个分支名称指向的提交结束:
...--A--B--C--D <-- parent/1.2.3
\
E--F <-- bug/12
这里E
和F
是修复错误的两个提交。 您现在单击变基并合并或压缩并合并并获得两个或一个新提交:
...--A--B--C--D--E'-F' <-- parent/1.2.3
\
E--F <-- bug/12
或者:
...--A--B--C--D--G <-- parent/1.2.3
\
E--F <-- bug/12
(我会用这张图,因为它更简单)。 你现在让 GitHub 删除它的bug/12
名称:
...--A--B--C--D--G <-- parent/1.2.3
\
E--F [abandoned]
在某个时候,在您的存储库中,您更新自己的 Git 对 GitHub Git 分支的内存:
...--A--B--C--D--G <-- origin/parent/1.2.3
\
E--F <-- origin/bug/12
请注意您的陈旧origin/bug/12
名称如何仍然记住提交F
!
此时,您可能会也可能不会向origin/parent/1.2.3
添加更多提交和/或更新您自己的parent/1.2.3
名称。 让我们再画一个提交并同步显示这两个提交:
...--A--B--C--D--G--H <-- parent/1.2.3, origin/parent/1.2.3
\
E--F <-- origin/bug/12
请记住,这是您存储库中内容的绘图。 GitHub 存储库有这个:
...--A--B--C--D--G--H <-- parent/1.2.3
它没有origin/*
名称:它只有它的分支名称。 您的Git 是具有origin/*
名称的 Git,包括陈旧的origin/bug/12
。 到目前为止,他们的Git 已经完全丢弃了提交EF
。 由于您的origin/bug/12
名称,您的Git 仍在保留其他不需要的EF
提交。
现在你在他们的Git 中做一些创建名称bug/12
事情,指向提交H
:
...--A--B--C--D--G--H <-- parent/1.2.3, bug/12
您现在在您的存储库中运行git fetch
(通过git pull
)。 你的 Git 看到他们的bug/12
指向提交H
。 你的 Git目前有这个:
...--A--B--C--D--G--H <-- parent/1.2.3, origin/parent/1.2.3
\
E--F <-- origin/bug/12
但是您的 Git 现在将获取您的origin/bug/12
并将其从提交F
拉出并将其移至指向提交H
:
...--A--B--C--D--G--H <-- parent/1.2.3, origin/parent/1.2.3, origin/bug/12
\
E--F [abandoned]
你的 Git 现在对你的名字origin/bug/12
执行这个不寻常的动作,将它从你仍然保留的提交中拉出来——提交F
到提交H
,它不是提交F
的后代。 (提交H
的唯一父级是G
G
的父级是D
,其父级是C
,其父级是B
。因此,提交H
不是F
的后代,尽管它们在提交B
共享相同的祖先。)操作是非快进的,因此您的Git 打印:
+ 6cca7ee...32eb5b2 bug/12 -> origin/bug/12 (forced update)
前面的加号(您省略了)表示这是强制更新,因为它是非快进的。
这里的两个散列 ID 6cca7ee
和32eb5b2
是我在上面调用F
和H
的提交的完整散列 ID 的缩写版本。 从输出git fetch
包括这两个散列ID之间的三个点,表明6cca7ee
不是的祖先32eb5b2
。
箭头左侧的名称bug/12
是在他们的存储库中看到的分支名称(在 GitHub 上,或任何地方)。 名称origin/bug/12
是您的 Git对其bug/12
的记忆。
最后的(forced update)
与加号和三个点表示相同的事情:这是一个非快进,因此作为强制更新完成。
因此, git fetch
命令已经三次告诉您有强制更新。
答案可能不是,但这取决于对origin/bug/12
更改,而是取决于您自己的分支名称。 在上面的图中,我们已经绘制了一些分支名称、一些远程跟踪origin/*
名称和一些其他 Git 的分支名称,具体取决于我们正在讨论的 Git 存储库。 但是我们还没有绘制所有的分支名称。
你的分支名称是你的。 他们可以指向你在你的存储库中的任何提交——包括其他Git,在 GitHub 上或任何地方,已经放弃的EF
提交。 如果您允许您的分支名称之一重新引入那些旧提交,那可能不太好。 如果您不允许这样做,那很好。 如果你没有任何分支名称指向这老提交,你会不小心再推出他们。
这就是解开谜题的关键。 提交才是最重要的。 提交有提交哈希 ID,世界各地的每个 Git 都同意这些提交获得这些哈希 ID。 没有其他提交,无论何时何地,都可以拥有这些哈希 ID! 您的Git 仍然在您的远程跟踪名称origin/bug/12
下保留它们。 它不再使用该名称:该名称已更新以记住其他一些提交哈希 ID。 但是你仍然有你的分支名称。 这些中的任何一个都记得与您的陈旧origin/bug/12
相同的哈希 ID,直到您的git pull
运行的git fetch
更新它,就在最近?
只有您可以回答这个问题,因为只有您拥有自己的Git 存储库。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.