Git 检出之前的提交

检出之前的提交

git checkout这个命令有三个不同的作用:检出文件、检出提交和检出分支。在这一章中,我们只关心前两种用法。

检出提交会使工作目录和这个提交完全匹配。你可以用它来查看项目之前的状态,而不改变当前的状态。检出文件使你能够查看某个特定文件的旧版本,而工作目录中剩下的文件不变。

用法

git checkout master

回到master分支。分支会在下一节中讲到,而现在,你只需要将它视为回到项目『当前』状态的一种方式。 git checkout <commit> <file> 查看文件之前的版本。它将工作目录中的<file>文件变成<commit>中那个文件的拷贝,并将它加入缓存区。 git checkout <commit> 更新工作目录中的所有文件,使得和某个特定提交中的文件一致。你可以将提交的哈希字串,或是标签作为<commit>参数。这会使你处在分离HEAD的状态。

最佳实践和例子

版本控制系统背后的思想就是『安全』地储存项目的拷贝,这样你永远不用担心什么时候不可复原地破坏了你的代码库。当你建立了项目历史之后,git checkout是一种便捷的方式,来将保存的快照『加载』到你的开发机器上去。

检出之前的提交是一个只读操作。在查看旧版本的时候绝不会损坏你的仓库。你项目『当前』的状态在 master上不会变化。在开发的正常阶段,HEAD一般指向master或是其他的本地分支,但当你检出之前提交的时候,HEAD就不再指向一个分支了——它直接指向一个提交。这被称为『分离HEAD』状态 ,可以用下图可视化: Git Tutorial: Checking out a previous commit

在另一方面,检出旧文件不影响你仓库的当前状态。你可以在新的快照中像其他文件一样重新提交旧版本。所以,在效果上,git checkout的这个用法可以用来将单个文件回滚到旧版本 。

Git Training: Checking out a previous version of a file

这个例子假定你开始了一个疯狂的实验,但你不确定你是否想要保留它。为了帮助你决定,你想看一看你开始实验之前的项目状态。首先,你需要找到你想要看的那个版本的ID。

git log --oneline

假设你的项目历史看上去和下面一样:

b7119f2 继续做些丧心病狂的事
872fa7e 做些丧心病狂的事
a1e8fb5 对hello.py做了一些修改
435b61d 创建hello.py
9773e52 初始导入

你可以这样使用git checkout来查看『对hello.py做了一些修改』这个提交: git checkout a1e8fb5 这让你的工作目录和a1e8fb5提交所处的状态完全一致。你可以查看文件,编译项目,运行测试,甚至编辑文件而不需要考虑是否会影响项目的当前状态。你所做的一切 都不会 被保存到仓库中。为了继续开发,你需要回到你项目的『当前』状态: git checkout master 这里假定了你默认在master分支上开发,我们会在以后的分支模型中详细讨论。

一旦你回到master分支之后,你可以使用 git revertgit reset来回滚任何不想要的更改。

如果你只对某个文件感兴趣,你也可以用git checkout来获取它的一个旧版本。比如说,如果你只想从之前的提交中查看hello.py文件,你可以使用下面的命令:

git checkout a1e8fb5 hello.py

记住,和检出提交不同,这里 确实 会影响你项目的当前状态。旧的文件版本会显示为『需要提交的更改』,允许你回滚到文件之前的版本。如果你不想保留旧的版本,你可以用下面的命令检出到最近的版本:

git checkout HEAD hello.py