30

我最近在只有我承诺的存储库上收到了来自 git 的“强制更新”警告。我还没有做任何重新定位,所以我不知道为什么会这样。我想知道的是,我应该在哪里查找可能丢失的更改?

为了说明,让存储库有三个副本,L、D 和 S(笔记本电脑、台式机、服务器)。

首先,所有三个存储库都是同步的。然后在 D 上完成工作并推送到 S。然后 L 运行git pull并获得“强制更新”。这是否意味着对 L 所做的更改已被覆盖,或者它们是否在其他地方?我怎样才能找到它们?谢谢。

4

3 回答 3

23

“强制更新”意味着远程跟踪分支是最近的。如果您在有人强制推送到存储库之后获取(或拉取),就会发生这种情况。

但是,在执行 时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随后被合并到本地分支中。

于 2012-08-21T22:17:49.327 回答
6

我想知道的是,我应该在哪里查找可能丢失的更改?

凯文写道,不会丢失任何地方历史是正确的。尽管如此,一些遥远的历史可能会丢失,尽管它会故意丢失。

例子

例如:

  • D 提交并推master送给 S。
  • L 取来。
  • D 改变主意(修改提交,或master以任何方式更改历史记录)。
  • D 将修改后的(非快进)推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回到主人那里。这可能需要首先提交任何本地更改。

好习惯

请注意,在未与其他用户适当合作的情况下将更改的历史记录推送到共享存储库被认为是一种不好的做法(因为这会给尚未共享更改的人带来额外的工作)。

换句话说,在共享存储库上进行获取时,看到“强制更新”应该不会让任何人感到惊讶。如果有人推送了一个错误的提交,他们应该考虑只推送一个更正的提交,而不是更改现有的历史。或者,他们应该在推动改变的历史之前与其他人达成协议。后一种选择在公共存储库上是不可能的。

于 2015-06-16T15:27:33.593 回答
1

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,我们在新的引用值中而不是在旧的引用值中遍历提交,以发现更新是否是强制更新

这导致在命令期间发生两件事:

  1. 包含 ref 更新的行末尾有一个附加的“(强制更新)”标记。

  2. 该远程分支的 ref 日志包含一点说更新是强制更新。

在许多情况下,这种强制更新消息很少发生,或者只是许多 ref 更新中的一小部分信息。
许多用户忽略了这些消息,但此处所需的计算显着减慢了他们的获取速度。
请记住,他们没有机会计算包含新获取的提交的提交图文件,因此这些比较可能非常慢。

添加--[no-]show-forced-updates允许用户跳过此计算的“”选项。
唯一永久的结果是删除 reflog 中的强制更新位。

包含一个fetch.showForcedUpdates允许此行为的新配置设置,而无需在每个命令中包含参数。
配置设置被命令行参数覆盖。

这意味着文档现在具有:

fetch.showForcedUpdates:

设置为false启用--no-show-forced-updates输入git-fetchgit-pull命令。
默认为真。

--show-forced-updates:

默认情况下,Git 在获取期间检查分支是否被强制更新。
这可以通过 禁用fetch.showForcedUpdates,但该--show-forced-updates选项保证进行此检查。

--no-show-forced-updates:

默认情况下,Git 在获取期间检查分支是否被强制更新。
出于性能原因,通过--no-show-forced-updates或设置fetch.showForcedUpdatesfalse 跳过此检查

如果在“ 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

于 2019-07-16T21:55:52.057 回答