引言
工作中经常会涉及到需要本地代码覆盖更新的操作。有时候可能是从远端git 上直接覆盖更新,或者是其他本地分支覆盖更新当前分支等等。这个时候就需要用到 reset 操作。
reset 操作分为三种类型:Soft、Mixed、Hard。今天我们就来说说这三种类型究竟如何使用。
一、Git 提交的三种状态
在解释 reset 的三种类型之前,我们需要了解 Git 提交的三种托管状态。不论你是用命令行,还是用图形化界面,都是如此。
第一种状态是“未暂存”、第二种状态是“已暂存”、第三种状态是“已提交”。
“未暂存”状态,是一种代码刚刚被修改过的状态。Git 不会记录你未暂存状态下多次修改之间的区别,它可以比较未暂存的代码与已提交代码之间的差异。
“已暂存”状态,是一种 Git 对修改代码进一步托管的状态,Git 管暂存区叫 Index。在 Index 区中的代码可以理解为处于一种即将提交的状态。
“已提交”状态,是一种 Git 对修改代码完成追踪的状态,Git 会记录本次提交,同时在时间线上生成一条 commit 记录,每条 commit 记录都会有一个唯一的 commit Id 。
如何理解提交的三种状态?我们可以以电商购物为例,来打个比方:
当我们浏览到我们喜欢的商品,给他们添加了一些备注或者将他们收藏,可以理解为一种简单的修改,那么此时,该商品已经处于“未暂存”状态。
如果我们对收藏的商品情有独钟,我们可以将 购物车理解为 暂存区(Index),将商品加入购物车的操作就可以理解为将修改代码添加到暂存区,此时商品就处于“已暂存”状态。
终于,我们下定决心购买这件商品,填写了必要的购买信息,比如电话、收货地址等后,点击付款,于是商品就处于了一种“已提交”的状态,并生成了一条订单号,可以类比我们的 commit id。
针对图形化的界面,如 Eclipse 中的 Git 插件,我们可以看到这样的区域:
二、Reset 三种类型
Reset 需要有一个参考标准,可以是本分支的其他提交点,也可以是本地其他分支的提交点,也可以是远程分支上的提交点。
比如,如果你希望直接将远程分支直接覆盖到本地,那么reset 的参考系就是远程分支上的最新一次 提交点。
当我们打开 Reset 对话框,可以看到我们需要选择的参考系,我们此时可以选择远程分支的最新提交点作为 reset 的参考系,在选择 Reset type 的时候,有三种选项:
Soft ,意思是只回退 HEAD 指针,HEAD 指针是 Git 在提交时间线上的某一个 提交点,一般而言,HEAD 和最新的提交是一致的。因为 git 有三级提交机制,因此 Soft 只回退 HEAD 的话,会回退与参考系提交点不同的所有提交记录,但暂存区和未暂存区会保留全部修改,同时被回退的提交记录中的所有修改会全部回退到暂存区。可以将 Soft 简单理解为将所有提交退回到暂存区,所有修改都会保留。
Mixed,意思是回退 HEAD 和 暂存区。即与参考提交点不同的所有提交,以及所有暂存区中未提交的修改,会全部回退到未暂存区。这是比较常用的 Reset 类型,它既会保留你的全部修改,同时又统一回退到所有代码“未暂存”状态。
Hard ,意思是强制回退或覆盖本地全部代码。这种回退类型不仅会回退与参考提交点不同的全部提交的代码,同时也会回退暂存的和未暂存的代码,将本地的全部代码与参考提交点完全保持一致,并且抛弃所有修改,不做保留。一般如果想直接覆盖本地代码,就可以选择 Hard 类型来操作。
总结
Reset 三种类型包括 Soft、Mixed、Hard。
从回退的力度来讲 Soft —> Mixed—> Hard 依次加重,分别对应
回退“已提交”—> 回退“已提交+已暂存”—> 回退“已提交+已暂存+未暂存” 。
两种常用场景:
1、如果想回退所有本地与远程不同的 commit ,同时又保留所有修改,可以选择 Soft 或 Mixed,推荐 Mixed。
2、如果想覆盖或回退本地代码,又不需要保留任何本地修改,可以选择 Hard 。