当git说“强制更新”时,可能会丢失什么内容?

时间:2012-08-21 21:31:10

标签: git

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

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

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

3 个答案:

答案 0 :(得分:20)

A"强制更新"表示远程跟踪分支是最近的。如果您在某人强行推送到存储库后获取(或拉取),则会发生这种情况。

但是,在执行git pull时,您当地的分支机构不会丢失任何历史记录。由于远程分支的历史记录现在与您的本地历史不同,git pull将执行合并。如果查看最近的提交(只运行git log),您应该看到合并提交,第一个父级是本地分支的先前状态,第二个父级是远程分支的新值。 / p>

为了说明,我刚刚复制了强制更新方案,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的fetch部分打印(forced update),但origin/master的新值随后会合并到本地分支中。

答案 1 :(得分:5)

  

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

凯文在写这篇文章的时候是对的,没有任何本地历史会丢失。 尽管如此,一些远程历史可能会丢失,但它会故意丢失。

实施例

例如:

  • D提交并将master推送到S.
  • L fetches。
  • D改变主意(修改提交,或以任何方式更改master的历史记录)。
  • D将修改后的(非快进)master推送到S.

在获取时,L将警告"强制更新"因为通过分支引用master无法再访问上一个分支提示。但无论如何都是D想要的。

寻找什么

来自Kevin的回答:

 + 7193788...a978889 master     -> origin/master  (forced update)

该行只会出现一次。对可能丢失的提交的引用是7193788。

如何探索

如果L想要保留对可能丢失的内容的引用,L可能在上面的示例中发出:git branch whateverbranchname 7193788。无论本地结账的当前状态如何,都可以这样做。

或者只是git checkout 7193788在分离头中探索它,然后例如git checkout master回到主人那里。这可能需要首先提交任何本地更改。

良好做法

请注意,如果没有与其他用户进行适当的合作,在共享存储库中推送已更改的历史记录会被视为不良做法(因为这会导致尚未共享更改的人员执行额外工作)

换句话说,没有人会惊讶地看到强制更新"在共享存储库上执行提取时。如果有人推送了一个错误的提交,他们应该考虑只是推送更正的提交,而不是更改现有的历史记录。或者,在推动改变历史之前,他们应该与其他人达成一致。后一种选择在公共存储库中是不可能的。

答案 2 :(得分:0)

Git 2.23(2019年第三季度)说明了何时检测到“强制更新”,并提出了显示它的选项。

请参见commit 3883c55commit 377444bcommit cdbd70cDerrick Stolee (derrickstolee)(2019年6月18日)。
(由Junio C Hamano -- gitster --commit cde9a64中合并,2019年7月9日)

  

fetch:添加--[no-]show-forced-updates自变量

     

在“ git fetch”期间更新了一组删除引用之后,我们将提交内容移到新的引用值中,而不是旧的引用值中,以发现更新是否为强制更新

     

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

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

  2.   
  3. 该远程分支的引用日志中包含一点说明更新是强制更新。

  4.   
     

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

     

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

     

包括一个新的fetch.showForcedUpdates配置设置,该设置允许   行为而不在每个命令中都包含参数。
  命令行参数会覆盖配置设置。

这意味着文档现在具有:

fetch.showForcedUpdates:
     

设置为false即可在--no-show-forced-updatesgit-fetch命令中启用git-pull
  默认为true。

--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配置设置来禁用这些消息。

config advice documentation现在包括:

fetchShowForcedUpdates:
     

git-fetch花很长时间计算参考更新后强制更新或警告禁用检查时显示的建议。