编辑我的代码后,"git checkout -- ." 可用于重置,但在 "git checkout [revision] ." 后它不会

After editing my code, "git checkout -- ." works for resetting, but after "git checkout [revision] ." it doesn't

编辑我的代码后,git checkout -- . 用于撤消我的编辑。但是,相同的命令不适用于撤消 git checkout [revision] . 所做的更改 - 在这种情况下我需要 git reset --hard;

谁能解释为什么不一致?

这一切都与 Git 的 index 有关。

索引在 Git 中有几个功能,但最主要的是它是您构建 next 提交的地方。其他版本控制系统没有单独的索引(或者完全对您隐藏它):它们只有 当前提交 ,这是显而易见的事情,Git 调用HEAD,以及 work-tree,您可以在其中查看和编辑文件。但是 Git 有这个额外的第三件事。

第三件事,这个索引,就是为什么你必须 git add 做出改变的原因。在您 git add 某些工作树文件的新版本之前,索引版本仍然与 HEAD 提交中的版本匹配。因此,您将进行的下一次提交还不会包含该文件的新版本。

命令:

git checkout -- .

索引复制文件,工作树。如果您还没有 git add 更新版本,索引版本与 HEAD 提交匹配,因此这会将与 HEAD 提交相同的版本复制到工作树。

命令:

git checkout <revision> -- .

然而,做了一些非常不同的事情:它将指定修订版中的所有内容复制到索引中,然后 然后 将这些文件从索引中复制到工作树中。现在每个文件的索引版本都改变了:

git checkout -- .

只是再次将那些相同的索引版本添加到您的工作树中。他们也都准备好提交新的提交。

您可以:

git checkout HEAD -- .

这会将 HEAD 提交中的所有文件复制到索引中,然后再复制到工作树中。这将使 HEAD、索引和工作树再次匹配。

同时,命令:

git reset --hard HEAD

有点不同,但最终效果是一样的:首先,它将当前分支从HEAD移动到HEAD。由于这不会将它移动 任何地方,因此根本没有任何效果。接下来,它将新 HEAD 的文件复制到索引中,最后,它将这些文件从索引复制到工作树(这是 --hard 步骤)。

如果索引中有新文件,您可以看到一些额外的差异,这些文件不在 HEAD 提交中。使用 git checkout HEAD -- . 会将它们留在那儿,而 git reset --hard HEAD 会将它们删除(从索引和工作树中)。

git checkout -- . 将丢弃工作目录中的更改并将所有文件的版本保留为最后一次提交(如您所说的撤消编辑)。

git checkout <commit> . 将根据指定更改所有文件的版本。有两种情况:

  • git checkout <last commit> .,这将与 git checkout -- . 相同,因为 git 将所有文件的版本更改为最后一次提交。
  • git checkout <not last version> .,这将按照您指定的版本检查所有文件的版本,并且由于文件与上次提交不同,因此需要提交本地更改。

总之,针对不同的情况:

撤消编辑(未提交): git checkout -- .

需要根据较早的提交进行开发: git checkout <commit> .git commit

放弃一些已提交的更改: git reset --hard HEAD~n