1

这是我今天早些时候发布的问题的后续问题,我是 git 新手,我正在尝试使用 git 分支。

我得到了

请在切换分支错误之前提交您的更改或存储它们。

这是我的 git 设置

我在 Master 分支中创建了一个文件 file1,然后添加并提交它。
我创建了一个分支 b1 并切换到该分支,在那里我对 file1 进行了一些更改并提交它。
我切换回 master,在那里我进行了一些更改但我没有提交它。
现在当我尝试切换到b1,我得到上面显示的错误..

我的问题是导致此错误的因素是什么?git 看到什么会引发此错误。


考虑一个单独项目的这种情况

我在 Master 分支中创建了一个临时文件,然后添加并提交它。
我创建了一个分支'branch1',现在 branch1 有一个临时文件的副本。
我在 Master 的临时文件中做了一些更改,但没有提交。

现在当我尝试切换到 branch1 时,为什么它没有抛出那个错误?据我了解,这两种情况都是相似的。但它会在第一种情况而不是第二种情况下引发该错误?

所以谁能向我解释一下,控制窗口之间切换的参数是什么?

4

4 回答 4

4

我切换回master,在那里我做了一些更改但我没有提交它。
现在当我尝试切换到b1时,我得到了上面显示的错误

master如果您对同时存在于和中的文件进行更改b1,您将在更改回 时收到该消息b1
分支b1将覆盖在master.

您的第二种情况对私有文件进行了修改(未在 git 中进行版本控制):更改分支不会影响其内容,因此无需存储。


你会在 codesearch 看到很多 git stash 的例子

你有没有发现自己这样做?

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

这是一个不错的小捷径:

$ git checkout --merge some_branch
于 2013-09-11T10:36:46.557 回答
2

已经有几个正确的答案,但这里有另一种看待它的方式。

想象一下,你被缩小了,被困在电脑里,被赋予了“成为git checkout命令”的工作。用户执行以下操作:

$ cd somewhere
$ ls
... various commands, etc
$ echo something_extra >> some_file
$ git checkout branch

所以现在,你去看看它需要什么git checkout branch。首先,您要了解要求您做事的人是否在 git repo 中(他在),以及他现在在哪个分支中(比如说master,为了具体起见)。所以可以切换分支,这似乎是他想要做的。

接下来,您需要查看切换分支所涉及的所有文件,包括 (maybe) some_file.

是否有some_filein branch的版本branchsome_file当前分支中是否有 的版本, master?如果有,它们是相同的还是不同的?当前的工作目录(以及,因为这是 git,“暂存区”,又名“索引”)呢?

这是您所有的可能性:

  • 该文件不在任何一个分支中。两种方式都没有跟踪,所以没问题!

  • 该文件在master但不在branch. 你应该删除它。

    现在,您需要检查删除它是否“安全”。如果它没有为提交而暂存并且文件的内容与master. (这意味着,你可能早点把它放在那里,当那个人这样做的时候git checkout master。)作为一个有点奇怪的案例,如果它现在不在那里也是“安全的”:没有什么可以删除的。

  • 该文件不在master但在branch. 您应该创建它,其内容如branch.

    现在,您需要检查创建它是否“安全”。如果它没有为提交而上演,并且现在也不存在,那么它是“安全的”。(理论上,如果它现在在那里但已经包含您应该放入其中的内容,它也应该是安全的。 git checkout不过,这里给了我一个错误——考虑到“奇怪”的情况,这很奇怪,git checkout通常允许切换。)

  • 该文件位于master branch中。你应该......好吧,这取决于!两者相同,还是两者不同

最后一种情况变得混乱,尤其是“索引”和“工作目录”之间的区别,但让我们来看看它们:

  • 该文件在两个分支中,并且在两个分支中都是相同的。你什么都不做,所以即使文件被暂存和/或修改,也可以切换分支。

  • 该文件在两个分支中,并且在两个分支中都不同。你应该替换它的内容。如果它没有暂存且没有修改(文件不git status显示任何内容),那么您就可以开始了。

  • 该文件在两个分支中,并且在两个分支中都不相同,并且工作目录中的文件与当前分支中的文件目标分支中的文件匹配。如果您更换它,您将丢失该人的更改,因此您必须出错。master branch

  • 这里的奇怪情况是:文件已暂存和/或修改,但现在与目标分支中的文件匹配。也就是说,有人对master已经在 中进行了相同的更改branch。在这种情况下,您不必覆盖文件,因此您可以切换分支。暂存区使这变得更加困难,因为当您进行结帐时,您首先必须将新内容写入暂存区,然后才将其复制到工作目录中。git checkout branch因此,在允许继续之前,您必须确保它在舞台区域中也相同(与目标分支版本相同) 。

但是,在所有情况下,您的工作是:“确保该人不会丢失他在工作目录或暂存区中所做的更改”。如果他失去一些变化,请抱怨并退出。否则,允许结帐,并更新暂存区和工作树。

(因为 git 的用户界面......好吧,我们不要说“故意敌对”:-) 而是“由于历史原因而变得复杂”,“切换分支”操作git checkout只是您可以做的许多不同事情之一git checkout. 特别是,git checkout rev path实际上是一个不同的命令,它不会切换分支,并且非常乐意覆盖更改。只要确保你只在git checkout branch这里做,而不是git checkout branch and some file names. 如果所有“覆盖”使用都有不同的动作动词,我会更高兴,但它就是这样。

我也跳过了“合并中间”的案例。如果你有合并冲突,暂存区总是被修改并且永远不会匹配,所以你在这里出错。如果没有合并冲突,checkout则照常进行,如果成功,则中止合并。我不确定我是否喜欢后一种操作——手动创建用户似乎更安全git merge --abort——但在这种情况下,任何“丢失”的工作都只是在合并期间做出的选择,就好像那是“仅仅是”......)

于 2013-09-11T21:56:47.737 回答
1

当您拥有的工作目录更改无法应用于其他分支中文件可用的更改时,您将收到错误消息。

在第一种情况下,master 和 branch 已经分道扬镳。file1中更改b1。它不在主人身上。但是您在 master 的版本上进行了本地更改,并切换了分支。现在无法应用更改,因为file1inb1的版本与 master 中的基本版本不同。

在场景 2 中,文件的基本副本在两个分支中是相同的。现在,签出任何分支时的本地更改都是相同的,您可以轻松地在它们之间切换。

于 2013-09-11T10:36:58.597 回答
0

切换分支时,git 会更改工作目录中的文件以匹配您要切换到的分支的文件。

但是,未提交的更改会发生什么?确切地说,它们将被覆盖。由于他们没有承诺,他们将永远失去。

为了防止这种情况发生,git 会发出一个警告,告诉您提交或存储这些未提交的更改。有几种方法可以消除该警告:

  • 无论如何切换分支(这将丢失未提交的更改)
  • 提交更改
  • 隐藏更改

无论如何切换分支都是通过在git reset --hard HEAD切换分支之前执行的。该命令将覆盖所有未提交的更改。

于 2013-09-11T10:38:50.427 回答