已经有几个正确的答案,但这里有另一种看待它的方式。
想象一下,你被缩小了,被困在电脑里,被赋予了“成为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_file
in branch的版本branch
?some_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
——但在这种情况下,任何“丢失”的工作都只是在合并期间做出的选择,就好像那是“仅仅是”......)