我最近在只有我承诺的存储库上收到了来自 git 的“强制更新”警告。我还没有做任何重新定位,所以我不知道为什么会这样。我想知道的是,我应该在哪里查找可能丢失的更改?
为了说明,让存储库有三个副本,L、D 和 S(笔记本电脑、台式机、服务器)。
首先,所有三个存储库都是同步的。然后在 D 上完成工作并推送到 S。然后 L 运行git pull
并获得“强制更新”。这是否意味着对 L 所做的更改已被覆盖,或者它们是否在其他地方?我怎样才能找到它们?谢谢。
我最近在只有我承诺的存储库上收到了来自 git 的“强制更新”警告。我还没有做任何重新定位,所以我不知道为什么会这样。我想知道的是,我应该在哪里查找可能丢失的更改?
为了说明,让存储库有三个副本,L、D 和 S(笔记本电脑、台式机、服务器)。
首先,所有三个存储库都是同步的。然后在 D 上完成工作并推送到 S。然后 L 运行git pull
并获得“强制更新”。这是否意味着对 L 所做的更改已被覆盖,或者它们是否在其他地方?我怎样才能找到它们?谢谢。
“强制更新”意味着远程跟踪分支是最近的。如果您在有人强制推送到存储库之后获取(或拉取),就会发生这种情况。
但是,在执行 时git pull
,您的本地分支不会丢失任何历史记录。由于远程分支的历史现在与您的本地不同,git pull
因此将执行合并。如果您查看最近的提交(只需 run git log
),您应该会看到一个合并提交,第一个父级是本地分支的先前状态,第二个父级是远程分支的新值。
为了说明,我刚刚复制了强制更新场景,并git pull
打印了以下内容:
> git pull
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 2 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (2/2), done.
From /Volumes/UserData/Users/kballard/Dev/Scratch/foo/server
+ 7193788...a978889 master -> origin/master (forced update)
Merge made by the 'recursive' strategy.
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 d
pull prints 的 fetch 部分(forced update)
,但是 的新值origin/master
随后被合并到本地分支中。
我想知道的是,我应该在哪里查找可能丢失的更改?
凯文写道,不会丢失任何地方历史是正确的。尽管如此,一些遥远的历史可能会丢失,尽管它会故意丢失。
例如:
master
送给 S。master
以任何方式更改历史记录)。master
送到 S。在 fetch L 将警告“强制更新”,因为之前的分支提示不再可以通过分支引用访问master
。但这就是D想要的。
来自凯文的回答:
+ 7193788...a978889 master -> origin/master (forced update)
那条线只会出现一次。对可能丢失的提交的引用是 7193788。
如果 L 想要保留对可能丢失的内容的引用,L 可能会在上面的示例中发出:git branch whateverbranchname 7193788
. 无论本地结账的当前状态如何,都可以这样做。
或者只是git checkout 7193788
在超然的头脑中探索它,然后例如git checkout master
回到主人那里。这可能需要首先提交任何本地更改。
请注意,在未与其他用户适当合作的情况下将更改的历史记录推送到共享存储库被认为是一种不好的做法(因为这会给尚未共享更改的人带来额外的工作)。
换句话说,在共享存储库上进行获取时,看到“强制更新”应该不会让任何人感到惊讶。如果有人推送了一个错误的提交,他们应该考虑只推送一个更正的提交,而不是更改现有的历史。或者,他们应该在推动改变的历史之前与其他人达成协议。后一种选择在公共存储库上是不可能的。
Git 2.23(2019 年第三季度)说明了何时检测到“强制更新”,并提出了不显示它的选项。
请参阅Derrick Stolee ( ) 的提交 3883c55、提交 377444b、提交 cdbd70c(2019 年 6 月 18 日)。(由Junio C Hamano 合并 -- --在提交 cde9a64中,2019 年 7 月 9 日)derrickstolee
gitster
fetch
: 添加--[no-]show-forced-updates
参数在“ ”期间更新一组删除引用后
git fetch
,我们在新的引用值中而不是在旧的引用值中遍历提交,以发现更新是否是强制更新。这导致在命令期间发生两件事:
包含 ref 更新的行末尾有一个附加的“(强制更新)”标记。
该远程分支的 ref 日志包含一点说更新是强制更新。
在许多情况下,这种强制更新消息很少发生,或者只是许多 ref 更新中的一小部分信息。
许多用户忽略了这些消息,但此处所需的计算显着减慢了他们的获取速度。
请记住,他们没有机会计算包含新获取的提交的提交图文件,因此这些比较可能非常慢。添加
--[no-]show-forced-updates
允许用户跳过此计算的“”选项。
唯一永久的结果是删除 reflog 中的强制更新位。包含一个
fetch.showForcedUpdates
允许此行为的新配置设置,而无需在每个命令中包含参数。
配置设置被命令行参数覆盖。
这意味着文档现在具有:
git fetch
:fetch.showForcedUpdates:
设置为
false
启用--no-show-forced-updates
输入git-fetch
和git-pull
命令。
默认为真。
--show-forced-updates:
默认情况下,Git 在获取期间检查分支是否被强制更新。
这可以通过 禁用fetch.showForcedUpdates
,但该--show-forced-updates
选项保证进行此检查。--no-show-forced-updates:
默认情况下,Git 在获取期间检查分支是否被强制更新。
出于性能原因,通过--no-show-forced-updates
或设置fetch.showForcedUpdates
为false
跳过此检查。如果在“
git-pull
”期间使用,该--ff-only
选项仍将在尝试快进更新之前检查强制更新。
和:
fetch
:警告分支列表中的强制更新' ' 中的
--[no-]show-forced-updates
选项git fetch
可能会让某些用户感到困惑,特别是如果它是通过配置设置而不是通过参数启用的。
添加建议以警告用户未列出(强制更新)消息。此外,当强制更新检查时间超过 10 秒时会警告用户,并建议他们禁用检查。
这些消息可以通过advice.fetchShowForcedUpdates
配置设置禁用。
配置建议文档现在 包括:
fetchShowForcedUpdates:
git-fetch
在 ref 更新后需要很长时间来计算强制更新时显示的建议,或警告检查已禁用。
请注意,该测试已在 Git 2.3.1/2.24(2019 年第四季度)中修复
请参阅SZEDER Gábor ( ) 的提交 814291c(2019 年 7 月 30 日)。(由Junio C Hamano 合并——在提交 8aa76ab中,2019 年 8 月 22 日)szeder
gitster
请参阅SZEDER Gábor ( ) 的提交 decfe05、提交 7f005b0、提交 12b1826(2019 年 8 月 1 日)。(由Junio C Hamano 合并 -- --在提交 77067b6中,2019 年 8 月 22 日)szeder
gitster