Git实用教程10.0:checkout 命令 与 reset 命令
本节主要知识点:
reset 命令 和 checkout 命令 的主要区别
再论 checkout
checkout 命令有两种功能:
从历史快照(或者暂存区域)中拷贝文件到工作目录
切换分支
功能1:从历史快照(或者暂存区域)中拷贝文件到工作目录
当给定某个文件名时,Git 会从指定的提交中拷贝文件到暂存区域和工作目录。比如执行 git checkout HEAD~ README.md
命令会将上一个快照中的 README.md 文件复制到工作目录和暂存区域中:
如果命令中没有指定具体的快照 ID,则将从暂存区域恢复指定文件到工作目录(git checkout README.md):
有些朋友可能会问:“上次看你在文件名的前边有加两个横杆(–),这次怎么就没有了呢?”
Git 提醒你写成 git checkout – README.md 的形式,那是为了预防你恰好有一个分支叫做 README.md,那么它就搞不懂你要恢复文件还是切换分支了,所以约定两个横杆(–)后边跟的是文件名。
反过来说,如果你确保你没有一个叫做 README.md 的分支,你直接写 git checkout README.md 也是妥妥的没问题啦
功能2:切换分支
那么我们就会发现 Git 的每一个命令虽然有多种使用方法,但是掌握了一定的门道,记住这些用法并不会很困难。
比如在你的印象中,checkout 命令就是用于切换分支,对不对?
那切换分支的操作,Git 是如何实现的呢?
首先我们知道 Git 的分支其实就是添加一个指向快照的指针,其次我们还知道切换分支除了修改 HEAD 指针的指向,还会改变暂存区域和工作目录的内容。
所以执行 git checkout 373c0 命令,Git 主要就是做了下边这两件事(当然事实上 Git 还做了更多):
回过头来,如果我们只想恢复指定的文件/路径,那么我们只需要指定具体的文件,Git 就会忽略第一步修改 HEAD 指向的操作,这不正跟之前讲 reset 命令的时候一样吗?
checkout 命令和 reset 命令的区别
checkout 命令和 reset 命令都可以用于恢复指定快照的指定文件,并且它们都不会改变 HEAD 指针的指向。
下面开始划重点:
它们的区别是 reset 命令只将指定文件恢复到暂存区域(–mixed),而 checkout 命令是同时覆盖暂存区域和工作目录。
注意:也许你试图使用 git reset --hard HEAD~ README.md
命令让 reset 同时覆盖工作目录,但 Git 会告诉你这是徒劳(此时 reset 不允许使用 --soft 或 --hard 选项)。
这样看来,在恢复文件方面,reset 命令要比 checkout 命令更安全一些。
reset 命令是用来“回到过去”的,根据选项的不同,reset 命令将移动 HEAD 指针(–soft) -> 覆盖暂存区域(–mixed,默认)-> 覆盖工作目录(–hard)。
checkout 命令虽说是用于切换分支,但前面你也看到了,它事实上也是通过移动 HEAD 指针和覆盖暂存区域、工作目录来实现的。
那问题来了:它们有什么区别呢?
下面开始划重点:
-
第一个区别是,对于 reset --hard 命令来说,checkout 命令更安全。因为 checkout 命令在切换分支前会先检查一下当前的工作状态,如果不是“clean”的话,Git 不会允许你这样做;而 reset --hard 命令则是直接覆盖所有数据。
-
另一个区别是如何更新 HEAD 指向,reset 命令会移动 HEAD 所在分支的指向,而 checkout 命令只会移动 HEAD 自身来指向另一个分支。
我们举例说明。
来,大家先把上节课的例子改成下边这样(大家应该知道怎么做吧,不会的就看文末的准备操作吧):
执行 git checkout feature
命令:
可以看到只是 HEAD 指针跑到 feature 分*儿去了。
好,我们执行 git checkout master
命令将其切回。
现在执行 git reset --hard feature
命令:
reset 命令将 HEAD 指向的分支以及 HEAD 本身都切到了 feature 分支里,换句话说,原来的快照已经被消失了(5.txt 那个快照不见了)。
以下内容属于部分人士查看(改成上面的例子)
准备操作:
在上节课结束时,是下面的情况:
step1:创建 feature 分支 并切换到 feature 分支:
step2:新建 4.txt 文件并添加到 git 仓库:
step3:切换回 master 分支:
step4:新建 5.txt 文件并添加到 git 仓库:
来看这个的同学前面还要在继续哦,没有掌握扎实!