git 由于本地更改导致结帐失败,但之后可以干净地应用存储

git checkout fails due to local changes but stash applies cleanly afterwards

我经常尝试签出一个新的远程分支(从中创建一个本地分支,但这可能与我的问题无关)并且 git 失败并出现以下错误

error: Your local changes to the following files would be overwritten by checkout:
Please, commit your changes or stash them before you can switch branches.

现在,当我看到这个时,人们可能会天真地认为如果存储更改、签出新分支然后应用存储的更改就会发生冲突,但情况几乎从未如此。所发生的事情是,隐藏的更改会干净地应用,并且我不会丢失在我签出新分支之前拥有的任何东西。为什么 git 给出这个看似误导性的错误? 如果我可以在签出前隐藏并在最后干净地应用隐藏,为什么 git checkout 不在幕后这样做?

编辑:
为了更清楚,我不是在问为什么结帐失败,或者为什么有时使用脏工作区结帐会成功,我理解所有这些。我的问题是,在这种情况下,有一个 100% 无数据丢失的操作过程(或者是否存在一些我没有看到的数据可能丢失的极端情况??)所以为什么 git 去做就对了?

如果我对 git 的新手说文件 foo 第 100 行的修改会与文件 foo 第 2 行的另一个修改冲突,那么他们接受它作为真理,不抱怨并且很容易解决冲突。但是因为 git 是一个很好的工具,它做的事情很聪明,甚至不会用它可以解决的非问题来打扰您,而不会造成任何损坏的风险。为什么在这种情况下 git checkout 的理念不同?

git checkout 命令会抱怨(并且不会切换分支)如果某些修改过的文件必须被擦除并由检出操作替换。

这意味着工作树版本和 HEAD 版本之间存在差异(以便修改文件) HEAD版本和目标提交(因此必须替换文件)。

并不意味着工作树版本和HEAD版本之间的差异与目标提交有任何冲突,只是目标提交不同来自 HEAD 提交和 HEAD 提交不同于工作树版本。例如,假设 README 的工作树版本在 35 行中的第 17 行将 "color" 的拼写更改为 "colour",并且从 HEAD 版本到目标版本在文件末尾添加注释(添加第 36 行)。在这种情况下,应用拼写更改也很简单,但 git checkout 不会那样做,它只会拒绝检查目标提交。

[编辑添加,来自评论] 并不是说​​ git checkout 不能进行合并,只是默认情况下不会。使用 git checkout -m 告诉 git checkout 使用合并代码。