更改分支不会丢弃本地更改

时间:2021-07-09 17:17:00

标签: git git-branch

所以,我有点困惑。

我对 git 不是很好,但我记得如果你在一个有未提交更改的分支中并且你试图签出另一个分支,git 要么不让你,要么放弃你的更改。

我还在 Chacon 和 Straub 所著的 Apress 的“Pro Git”一书中检查了这种行为是否正确。

enter image description here

还有

enter image description here

我承认我的英语不是很好,但我记得这种解释是正确的,因为我过去经常使用 git。或者我在更改分支时放弃未提交的更改是错误的吗?我是否理解这本书所说的错误?

如果我是对的,为什么我的存储库将更改的文件从一个分支移动到另一个分支?您可以在此处检查行为:

enter image description here

<块引用>

使用 git status 检查我是否在主分支中并且它没有被更改。

<块引用>

创建一个新分支并移动到它。

<块引用>

进行一些随机更改,例如使用 ed 删除几行。

<块引用>

改回主分支。

<块引用>

令人惊讶的是,git diffgit status 表明该文件也在 main 上发生了更改。

git 不应该阻止我更改分支或丢弃我的更改吗?这非常令人困惑,我花了一段时间才意识到如果我没有对其进行任何更改,为什么我的主分支会出现意外行为。

git version 2.30.1 (Apple Git-130)


编辑:有些答案说git switchgit checkout 不同。我仍然不确定是不是这样,因为不同的人(和文档)会说不同的东西。

但是,我也尝试过使用 git checkout 进行相同的操作,它还会移动文件,而不是阻止我切换或警告我工作目录中的差异。

您可以看到 git checkout 执行以下相同操作:

enter image description here

3 个答案:

答案 0 :(得分:2)

当您切换分支时,未提交的更改将保持不变。否则,像切换分支这样无害的操作会默默地删除您所做的任何本地工作。这不好(用户会抱怨;这是理所当然的)。

请记住:您的工作树中的本地更改链接到任何分支。它们只存在于您的工作树中。

您的第一个引用/屏幕截图仅讨论已提交的更改:当您切换分支时,您的工作目录将反映切换到分支的内容。它还提到“如果 Git 不能干净地做到这一点”(强调我的)——这意味着只有在本地(未提交)和另一个分支中更改了相同的文件时,Git 才会中止。

第二个引用明确提到“未提交的更改冲突”。在这种情况下,Git 将拒绝切换分支。您可以提交更改、删除它们或隐藏它们 - 之后,您可以切换到另一个分支。

只有在分支之间的(提交的)文件不同时才会发生冲突。切换分支时的“冲突检测”不考虑本地未提交的更改。

git checkout 的这种行为一直是相同的。 git switch(一种较新的结帐替代方法)的行为方式相同。

答案 1 :(得分:1)

问题的关键在于您描述的行为适用于 git checkout 命令,但您使用的是相对较新的 git switch 命令来更改分支。您引用的文档说“当您切换分支时”使情况变得更加复杂,但它们也可能指的是 git checkout

如果您使用 git switch,并且您的本地更改与切换到的分支不冲突,则本质上它只会切换并移动您的更改。

From the docs

<块引用>

切换到指定的分支。更新工作树和索引以匹配分支。所有新提交都将添加到此分支的顶端。

...

切换分支不需要干净的索引和工作树(即与 HEAD 相比没有区别)。但是,如果操作导致本地更改丢失,则操作将中止,除非使用 --discard-changes--merge

另有说明

答案 2 :(得分:0)

注意事项

首先要知道:每次提交都包含您的所有文件。

要知道的第二件事:签出或切换到提交意味着用该提交中所有内容的副本完全替换可见文件(工作树)。

切换到新分支

一个常见的用例是,您在分支 A 上编辑和/或添加一些文件,然后您将要提交,然后您突然想:等等,不,我应该在新分支上执行此操作。所以你创建一个新的分支并切换到它,一切都很好;你所有的工作都会跟着你到新的分支。为什么?

因为签出新分支没有效果。分支只是您已经进行的同一个提交的新名称。

切换到旧分支

好的,现在考虑不同的情况。

在新分支上编辑添加和提交,然后开始编辑文件。您突然决定切换回第一个分支。

这意味着您要求 Git 用第一个分支表示的提交中的内容替换您的所有文件。这可能是一个非常彻底的变化。不过,通常 Git 很乐意这样做。

但是您正在编辑文件。如果该文件已被 git 跟踪,则替换或删除它会破坏未提交的工作。所以 Git 拒绝了。

当您检出分支时,Git 不会永远覆盖您未提交的更改。

粉碎一切

但是……

如果您要求检出或恢复一个特定文件,那么 Git 会假设您知道自己在做什么,并且会让您粉碎自己未提交的工作。与硬重置类似。这些东西本质上是具有破坏性的,Git 只会退缩,让你成为破坏性的。

相关问题