这周上班的时候,一个同事发了一个如下的截图问我IDEA的代码回滚这三种操作有什么区别?当时也回答得寥寥草草的,平时用hard比较多也没太注意这个细节,所以写篇文章记录一下,也希望能帮助到大家。
实际上git版本回滚有三种操作方式: 根据–soft –mixed –hard,会对工作区working tree、暂存区index和历史记录repository(HEAD)进行重置,每种操作重置的方式不一样。下面我们看看三种方式的具体区别
(1)git reset --mixed commit_id
使用mixed回退到commit_id这个版本号时,回退的是commit和暂存区index修改的信息,这些修改的内容都会在工作区里保留,即相当于前面的修改的内容都被回退到本地工作区里。(备注:直接用 git reset 不带任何参数时,默认为--mixed方式回退)
示例一:先项目的pom.xml文件修改并提交,然后再修改ConsumerProxy这个类并提交,最后通过log查看commit信息历史记录如下图。(log命令的相关操作参考:git log和git reflog的区别)
假如现在使用 --mixed 将代码回滚到第一次提交的状态,看看发生了什么?被reset掉的commit修改内容被保存在工作区里,而不是直接丢弃掉。
示例二:先项目的pom.xml文件修改并提交,然后再修改ConsumerProxy这个类并提交,最后修改ConsumerMessage后直接add到index中,通过status和log查看commit信息历史记录如下图。注意:此时pom和ConsumerProxy的修改被commit到repository中,ConsumerMessage类的修改只是被add到暂存index中。
假如现在使用 --mixed 将代码回滚到第一次提交的状态,看看发生了什么?被reset掉的commit和暂存区index中的修改内容都被保存在工作区里,而不是直接丢弃掉。
(2)git reset --soft commit_id
使用--soft回退到commit_id这个版本,只回退了commit的信息,不会恢复到暂存区index file的修改,暂存区index修改的内容还保存在里面,不会变;如果还要将暂存区里的内容提交,直接commit即可。
示例:先项目的pom.xml文件修改并提交,然后再修改ConsumerProxy这个类并提交,最后修改ConsumerMessage后直接add到暂存index中,通过status和log查看commit信息历史记录如下图。注意:此时pom和ConsumerProxy的修改被commit到repository中,ConsumerMessage类的修改只是被add到index中。
假如现在使用 --soft 将代码回滚到第一次提交的状态,看看发生了什么?被reset掉的信息中,commit的修改内容都被保存在index中,而原先index里的修改内容还是原样在index中。
(3)git reset --hard commit_id
彻底回退到某个版本,本地的代码会变为上一个版本的内容,修改的内容全部被丢掉;不管是commit的修改,还是暂存区index中修改的内容都不会被保留,此命令 慎用!一旦回滚,使用log是找不回来commit_id的,只能借助于reflog(参考:【git log和git reflog的区别】)。
示例:先将项目的pom.xml文件修改并提交,然后再修改ConsumerProxy这个类并提交,最后修改ConsumerMessage后直接add到index中,通过status和log查看commit信息历史记录如下图。注意:此时pom和ConsumerProxy的修改被commit到repository中,ConsumerMessage类的修改只是被add到index中。
假如现在使用 --hard 将代码回滚到第一次提交的状态,看看发生了什么?被reset掉的所有信息都全部丢掉了,够暴力吧。
#返回到当前版本的上一个版本
git reset --hard HEAD^
#(上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100)
(4)总结
版本回滚操作 --mixed 和 --soft都可以将reset掉的修改信息保存下来;而 --hard 操作很暴力,会直接将修改信息给抛弃掉,此命令 慎用!
2021年03月14日 晚 于北京记