git checkout 和 git reset 的区别 —— Git 学习笔记 09

git checkout 和 git reset 的区别

git checkout 和 git reset 有时候让人困惑,因为它们的表现很相似。本文浅析二者之异同。

后接分支名称

运行 git checkout [branch] 与运行 git reset --hard [branch] 非常相似,都会更新所有的三棵树(关于三棵树可以参考我的博文 git reset 命令详解),使其看起来像 [branch],不过有两点重要的区别。

首先不同于 reset --hardcheckout 对工作目录是安全的,它会通过检查来确保不会将已更改的文件弄丢;而 reset --hard 则会不做检查就全面地替换所有东西。

第二个重要的区别是如何更新 HEAD。 reset 会移动 HEAD 分支的指向(即 HEAD 指向的分支的指向),而 checkout 只会移动 HEAD 自身来指向另一个分支。
这里写图片描述

例如,假设我们有 master 和 develop 分支,它们分别指向不同的提交(上图左边);我们现在在 develop 上(所以 HEAD 指向它)。 如果我们运行 git reset master,那么 develop 会和 master 指向同一个提交; 而如果我们运行 git checkout master 的话,develop 不会移动,HEAD 自身会移动,指向 master。

所以,虽然在这两种情况下我们都移动 HEAD 使其指向了提交 A,但做法是非常不同的。 reset 会移动 HEAD 分支的指向,而 checkout 则移动 HEAD 自身。

有人会问,git reset --hard [branch],这种用法有什么用?我能想到的一个例子是,

假设仓库是这样:

这里写图片描述

为了将本地的状态回退到和远程的一样,可以执行:

$ git reset --hard origin/master   

执行后如下图:

这里写图片描述

后接路径

运行 checkout 的另一种方式是指定一个文件路径,这会像 reset 一样,不会移动 HEAD。 它就像是 git reset --hard [branch] file,不仅用某次提交中的那个文件来更新索引,同时也会覆盖工作目录中对应的文件 —— 这样对工作目录并不安全!

注:这里的 [branch] 是分支名称,也可以是 commit 或者是 HEAD 一类的符号引用。本质上,它们最终都定位到某个提交。

速查表

下面的速查表列出了命令对树的影响。 “HEAD” 一列中的 “REF” 表示该命令移动了 HEAD 指向的分支引用,而‘HEAD’ 则表示只移动了 HEAD 自身。 特别注意 WD Safe? 一列 ,表示工作目录是否安全,如果它标记为 NO,那么运行该命令之前请仔细考虑一下。

这里写图片描述

参考资料

《Pro Git》(Scott Chacon, Ben Straub Version 2.1.14, 2018-05-19)

  • 10
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值