git checkout 由于本地更改而失败,但 stash 之后会干净地应用

标签 git git-stash git-checkout

我经常尝试 checkout 一个新的远程分支(从中创建一个本地分支,但这可能与我的问题无关)并且 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.

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

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

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

最佳答案

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

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

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

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

关于git checkout 由于本地更改而失败,但 stash 之后会干净地应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35139991/

相关文章:

git - 错误 : pathspec 'test-branch' did not match any file(s) known to git

git - 允许所有用户在 TFS-GIT 中创建一个 repo

git - 在 git stash pop 之后撤消 git reset --hard

git - 撤消 IntelliJ 智能 checkout

git - 更新**不是**当前分支(在 Git 中)

git - 有没有办法在 git checkout 中使用通配符?

git - 为什么暂存目录也叫 Index/Git Index?

git - 通过 Ansible 应用 git 补丁的最佳方法

git - 文件不存在但 git 认为它存在

git - git 可以使用 stash 对工作副本进行比较吗