检出历史提交
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 checkout
的这个用法可以用来将单个文件回滚到旧版本 。
例子
查看之前的版本
这个栗子假定你开始了一个疯狂的实验,但你不确定你是否想要保留它。为了帮助你决定,你想看一看你开始实验之前的项目状态。首先,你需要找到你想要看的那个版本的 ID。
1 | git log --oneline |
假设你的项目历史看上去和下面一样:
1 | b7119f2 继续做些丧心病狂的事 |
你可以这样使用 git checkout
来查看「对 hello.py 做了一些修改」这个提交:
1 | git checkout a1e8fb5 |
这让你的工作目录和 a1e8fb5
提交所处的状态完全一致。你可以查看文件,编译项目,运行测试,甚至编辑文件而不需要考虑是否会影响项目的当前状态。你所做的一切 都不会 被保存到仓库中。为了继续开发,你需要回到你项目的「当前」状态:
1 | git checkout master |
这里假定了你默认在 master 分支上开发,我们会在以后的分支模型中详细讨论。
一旦你回到 master 分支之后,你可以使用 git revert
或 git reset
来回滚任何不想要的更改。
检出文件
如果你只对某个文件感兴趣,你也可以用 git checkout
来获取它的一个旧版本。比如说,如果你只想从之前的提交中查看 hello.py
文件,你可以使用下面的命令:
1 | git checkout a1e8fb5 hello.py |
记住,和检出提交不同,这里 确实 会影响你项目的当前状态。旧的文件版本会显示为「需要提交的更改」,允许你回滚到文件之前的版本。如果你不想保留旧的版本,你可以用下面的命令检出到最近的版本:
1 | git checkout HEAD hello.py |
这篇教程来源于「git-recipes」