6.检出历史提交

检出历史提交

git checkout

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

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

用法

1
git checkout master

回到 master 分支。分支会在下一节中讲到,而现在,你只需要将它视为回到项目「当前」状态的一种方式。

1
git checkout <commit> <file>

查看文件之前的版本。它将工作目录中的 <file> 文件变成 <commit> 中那个文件的拷贝,并将它加入缓存区。

1
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。

1
git log --oneline

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

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

你可以这样使用 git checkout 来查看「对 hello.py 做了一些修改」这个提交:

1
git checkout a1e8fb5

这让你的工作目录和 a1e8fb5 提交所处的状态完全一致。你可以查看文件,编译项目,运行测试,甚至编辑文件而不需要考虑是否会影响项目的当前状态。你所做的一切 都不会 被保存到仓库中。为了继续开发,你需要回到你项目的「当前」状态:

1
git checkout master

这里假定了你默认在 master 分支上开发,我们会在以后的分支模型中详细讨论。

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

检出文件

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

1
git checkout a1e8fb5 hello.py

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

1
git checkout HEAD hello.py

这篇教程来源于「git-recipes」