当 git 说“强制更新”时,人们可能会丢失什么以及在哪里丢失东西?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12063345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 07:23:20  来源:igfitidea点击:

What and where does one potentially lose stuff when git says "forced update"?

git

提问by Sean Whitton

I recently received a "forced update" warning from git on a repository which only I commit to. I haven't done any re-basing so I don't know why this happened. What I want to know is, where should I look to find changes that have potentially been lost?

我最近在一个只有我提交的存储库上收到了来自 git 的“强制更新”警告。我没有做过任何重新定位,所以我不知道为什么会发生这种情况。我想知道的是,我应该在哪里寻找可能丢失的更改?

To illustrate, let there be three copies of the repository, L, D and S (laptop, desktop, server).

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

To begin all three repositories are in-sync. Then work is done on D and pushed to S. Then L runs git pulland gets "forced update". Does this mean that there are changes made on L that have been overwritten, or are they somewhere else? How can I find them? Thanks.

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

采纳答案by Lily Ballard

A "forced update" means the remote-tracking branch was recent. This happens if you fetch (or pull) after someone does a force push to the repository.

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

However, when executing the git pull, your local branch won't lose any history. Since the remote branch's history now diverges from your local, git pullwill execute a merge. If you look at the most recent commit (just run git log) you should see a merge commit, with the first parent being the previous state of your local branch and the second parent being the new value of your remote branch.

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

For illustration, I just reproduced the forced update scenario, and a git pullprints the following:

为了说明,我只是复制了强制更新场景,并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

The fetch portion of the pull prints (forced update), but the new value of origin/masteris subsequently merged into the local branch.

pull 的 fetch 部分打印(forced update),但 的新值origin/master随后合并到本地分支中。

回答by Stéphane Gourichon

What I want to know is, where should I look to find changes that have potentially been lost?

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

Kevin is right when writing that no local history will be lost. Still, some remote history may be lost, though it will be lost on purpose.

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

Example

例子

For example:

例如:

  • D commits and pushes masterto S.
  • L fetches.
  • D changes mind (amends a commit, or changes history of masterin whatever way).
  • D pushes the modified (non-fast-forward) masterto S.
  • D 提交并推master送到 S。
  • L 取。
  • D 改变主意(修改提交,或master以任何方式更改历史记录)。
  • D 将修改后的(非快进)推master送到 S。

On fetch L will warn "forced update" because the previous branch tip is no longer reachable through the branch reference master. But that's what D wanted anyway.

在 fetch L 将警告“强制更新”,因为前一个分支提示不再可通过分支引用访问master。但无论如何,这就是 D 想要的。

What to look for

要找什么

From Kevin's answer:

来自凯文的回答:

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

That line will appear only once. The reference to the possibly lost commit is 7193788.

那条线只会出现一次。对可能丢失的提交的引用是 7193788。

How to explore it

如何探索它

If L wants to keep a reference to what might be lost, L might in above example issue: git branch whateverbranchname 7193788. This may be done whatever the current state of the local checkout.

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

Or just git checkout 7193788to explore it in detached head, then e.g. git checkout masterto get back to master. This may require to first commit any local change.

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

Good practice

良好做法

Notice that it's considered bad practice to push a changed history on a shared repository without proper cooperation with other users(because it causes extra work for people who have changes not yet shared).

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

In other words, no one should be surprised to see a "forced update" when doing a fetch on a shared repository. If someone pushed a bad commit, they should consider just pushing a corrected commit on top, not change existing history. Alternatively, they should get into agreement with others before pushing a changed history. That latter option is not possible on a public repository.

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

回答by VonC

Git 2.23 (Q3 2019) illustrates when a "forced update" is detected, and propose the option to notshow it.

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

See commit 3883c55, commit 377444b, commit cdbd70c(18 Jun 2019) by Derrick Stolee (derrickstolee).
(Merged by Junio C Hamano -- gitster--in commit cde9a64, 09 Jul 2019)

请参阅Derrick Stolee ( ) 的commit 3883c55commit 377444bcommit cdbd70c(2019 年 6 月 18 日(由Junio C Hamano合并-- --cde9a64 提交中,2019 年 7 月 9 日)derrickstolee
gitster

fetch: add --[no-]show-forced-updatesargument

After updating a set of remove refs during a 'git fetch', we walk the commits in the new ref value and not in the old ref value to discover if the update was a forced update.

This results in two things happening during the command:

  1. The line including the ref update has an additional "(forced-update)" marker at the end.

  2. The ref log for that remote branch includes a bit saying that update is a forced update.

For many situations, this forced-update message happens infrequently, or is a small bit of information among many ref updates.
Many users ignore these messages, but the calculation required here slows down their fetches significantly.
Keep in mind that they do not have the opportunity to calculate a commit-graph file containing the newly-fetched commits, so these comparisons can be very slow.

Add a '--[no-]show-forced-updates' option that allows a user to skip this calculation.
The only permanent result is dropping the forced-update bit in the reflog.

Include a new fetch.showForcedUpdatesconfig setting that allows this behavior without including the argument in every command.
The config setting is overridden by the command-line arguments.

fetch: 添加--[no-]show-forced-updates参数

在“ git fetch”期间更新一组删除引用后,我们在新引用值而不是旧引用值中遍历提交,以发现更新是否是强制更新

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

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

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

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

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

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

That means the documentation now has:

这意味着文档现在有:

fetch.showForcedUpdates:

Set to falseto enable --no-show-forced-updatesin git-fetchand git-pullcommands.
Defaults to true.

fetch.showForcedUpdates:

设置为false启用--no-show-forced-updatesingit-fetchgit-pull命令。
默认为真。

--show-forced-updates:

By default, Git checks if a branch is force-updated during fetch.
This can be disabled through fetch.showForcedUpdates, but the --show-forced-updatesoption guarantees this check occurs.

--no-show-forced-updates:

By default, Git checks if a branch is force-updated during fetch.
Pass --no-show-forced-updatesor set fetch.showForcedUpdatesto falseto skip this check for performance reasons.

If used during 'git-pull' the --ff-onlyoption will still check for forced updates before attempting a fast-forward update.

--show-forced-updates:

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

--no-show-forced-updates:

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

如果在“ git-pull”期间使用,该--ff-only选项仍将在尝试快进更新之前检查强制更新。

And:

和:

fetch: warn about forced updates in branch listing

The --[no-]show-forced-updatesoption in 'git fetch' can be confusing for some users, especially if it is enabled via config setting and not by argument.
Add advice to warn the user that the (forced update) messages were not listed.

Additionally, warn users when the forced update check takes longer than ten seconds, and recommend that they disable the check.
These messages can be disabled by the advice.fetchShowForcedUpdatesconfig setting.

fetch:警告分支列表中的强制更新

--[no-]show-forced-updates' git fetch' 中的选项可能会让某些用户感到困惑,特别是如果它是通过配置设置而不是通过参数启用的。
添加建议以警告用户未列出(强制更新)消息。

此外,当强制更新检查时间超过十秒时警告用户,并建议他们禁用检查。
这些消息可以通过advice.fetchShowForcedUpdates配置设置禁用。

The config advice documentationnow includes:

配置建议文档现在包括:

fetchShowForcedUpdates:

Advice shown when git-fetchtakes a long time to calculate forced updates after ref updates, or to warn that the check is disabled.

fetchShowForcedUpdates:

当看到建议git-fetch需要很长的时间参考更新后,计算出强制更新,或以警告检查功能。

Note, the test is fixed in Git 2.3.1/2.24 (Q4 2019)

请注意,该测试已在 Git 2.3.1/2.24(2019 年第四季度)中修复

See commit 814291c(30 Jul 2019) by SZEDER Gábor (szeder).
(Merged by Junio C Hamano -- gitster--in commit 8aa76ab, 22 Aug 2019)

请参阅SZEDER Gábor ( ) 的提交 814291c(2019 年 7 月 30 日(由Junio C Hamano合并-- --8aa76ab 提交中,2019 年 8 月 22 日)szeder
gitster

See commit decfe05, commit 7f005b0, commit 12b1826(01 Aug 2019) by SZEDER Gábor (szeder).
(Merged by Junio C Hamano -- gitster--in commit 77067b6, 22 Aug 2019)

参见SZEDER Gábor ( ) 的commit decfe05commit 7f005b0commit 12b1826(01 Aug 2019 )(由Junio C Hamano合并-- --提交 77067b6 中,2019 年 8 月 22 日)szeder
gitster