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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013490896/article/details/82314102

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)

猜你喜欢

转载自blog.csdn.net/u013490896/article/details/82314102