Git实用教程 8.0:checkout 命令 与 reset 命令

这节课我们来重新回顾一下 checkout 命令,然后我们再来讲讲 reset 命令(忘了的可以查看Git实用教程 4.0:回到过去) 和 checkout 命令 的主要区别。


再论 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 命令功能重叠了? 

现在我就来为大家庖丁解牛!

恢复文件

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 仓库:

over,大功告成,来看这里的操作答案的童鞋自己好好反省啊,前面的文章肯定没有好好看。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值