Git使用手册/Git教程:git reset使用详解/git reset --mixed --soft --hard使用详解及区别/git代码版本回滚回退
相关文章:
关于GIT Checkout的使用,请参考文章:Git使用手册:git checkout 创建分支、切换分支
关于Git status命令使用解读,请参考文章:Git使用手册:git status 查看本地工作区、暂存区中文件的修改状态
关于Git diff和Git add命令使用,请参考文章:Git使用手册:git diff 、 git add 、 git diff --cached 命令详解
关于Git commit命令使用详解,请参考文章:Git使用手册:git commit -m/-am/-a -m 提交文件至本地仓库区
关于Git fetch命令使用,请参考文章:Git使用手册:git fetch 将远程仓库的分支及分支最新版本代码拉取到本地
关于Git pull命令使用,请参考文章:Git使用手册:git pull origin 拉取代码到本地,解决拉取代码时发生的文件冲突
关于Git push命令使用,请参考文章:Git使用手册:git
push 推送提交本地仓库代码文件到远程仓库
关于Git reflog命令使用,请参考文章:Git使用手册/Git教程:git reflog使用、查看历史版本记录
本篇文章主要围绕git reset使用、git版本回退、git reset --mixed --soft --hard的区别进行讲解
可以看到上一次提交时间为2018年1月18日 9:24:05,commit id为b43e635
我们再使用git reflog查看提交版本历史记录(这里我们指定显示5条记录),如图所示:
图中同样显示了5条记录,并且显示出了缩短的7位版本号、HEAD值和描述信息。
这时我们将当前工作区内容进行暂存并提交,如图:
然后再使用git log 看一下提交版本历史(同样显示5条记录):
这里我们会发现提交版本历史中提一条提交时间为2018年1月29日 17:24:51,commit id为c769c03,这个就是我们刚刚进行的提交。
我们再使用git
reflog查看提交版本历史记录(这里我们指定显示5条记录),如图所示:
同样也可以看到最新的提交,commit id为c769c03,此时最新的提交的HEAD值为[email protected]{0},也可以用HEAD~0表示。
此时我们执行 git reset --mixed head命令进行版本回退,这里我们回退的是最新版本,如图:
图中执行了2句命令,分别是回退至最新版本,查看提交版本记录(显示5条)。
这里我们可以看到,当我们执行git reset --mixed HEAD~0 时,表示我们回退到了commit id为c769c03的版本,也就是最新的版本,这时使用git log查看提交历史时,提交版本记录没有发生变化,commit id为c769c03的提交记录仍然是最新的版本。
这时我们使用git reflog查看一下提交版本历史,如图所示:
我们发现一个问题,这里与git log显示的内容不同,commit id为c769c03的版本出现了两次。上一次为我们刚刚进行操作的记录,最新一次为我们进行reset的记录。
这时我们再执行一次回退命令,回退到上上个版本,如图:
图中可以看到,我们使用的命令为git reset --mixed HEAD~2,也就是我们向上回退了2个版本。同时执行命令后,出现了提示:Unstaged changes after reset 表示本地工作区在执行reset后发生了变化,具体变化已经列出来了。也就是下面一行:
M src/main/java/com/xiduoduo/web/controller/APISelfTestController.java
其中M开头表示修改,后面为文件路径,即指定文件发生了修改。
这时我们再使用git log查看一下提交版本历史记录:
我们结合使用git reset --mixed HEAD~0时使用的git log的图片,对照上图来看。从图中我们可以看出,此时git log显示的内容中,第一条记录的commit id已经变为了对于c769c03版本来说的上上个版本,也就是commit id 为c3b8692的版本。
同时,我们之前提到的commit id为c769c03的版本以及c769c03的下一个版本,也就是我们退回到现在这个版本的上个版本和上上个版本的提交版本历史记录均已经再git log中消失了。
此时我们再执行git reflog查看提交版本历史记录:
图中我们可以看到,最新的一条提交版本记录的commit id为c3b8692,确实是我们这次指定回退的版本的commit id ,HEAD值为[email protected]{0},操作为reset移动到了HEAD~2。同时下面可以看到git log中消失的c769c03和b43e635两个版本及其操作。
此时我们查看本地工作区状态:
发现当前工作区中的文件确实文件已经变更为了修改状态,处于待暂存、待提交状态。
由此我们可以得出以下结论:
使用该命令后,会将指定版本为起始点,将起始点后的所有新增或修改后的代码保留,同时回退commit和index信息。
也就是说起始点后所有的新增和修改,都未添加到暂存区和本地仓库中。若需要继续提交变动及新增的文件,需要先将这些进行’存入暂存区’操作, 再进行’提交到本地仓库’操作,即:git add . 和 git commit –m ‘描述信息’ 两句命令,或使用git commit–am ‘描述信息’ 合并执行’存入暂存区’及’提交本地仓库’这两步操作,具体可以查看我之前的文章:git add 使用、git commit 使用。
命令:git reset --soft HEAD~1
如图所示:
再执行git log命令查看提交版本历史记录:
最新的提交版本历史记录的commit id是:69b64e2,结合执行命令前,我们使用git log查看的结果来看,正是之前我们刚进行提交操作的上一个版本。
从结果可以看出,回退版本成功了,但刚刚的提交却消失了。
我们再执行git status查看当前工作区的状态:
发现工作区中有文件发生了变化,回退版本起始点后的代码仍然存在,且已经存入暂存区了,可以直接进行提交。
我们执行提交操作,同时查看提交版本历史记录:
提交后,从git log反映的结果中,看到最新的提交为我们刚刚进行的提交操作,commit id为813a2a9,但再git log出现的结果中,仍未看到commit id为d53cb76的那次提交操作。
由此我们可以得出以下结论:
使用该命令后,会将指定版本为起始点,将起始点后所有的新增或修改后的代码保留,同时仅回退commit信息,不回退index信息。
也就是说起始点后的所有新增和修改,都已经存入暂存区中了,若需要进行提交的话,可以直接使用git commit 命令进行提交操作。
图中,我们对testResetSoft方法体进行了修改,同时新增了方法testResetHard,如红框所示。同时我们进行查看工作区状态、存入缓存区、提交到本地仓库这三个操作,如图所示:
命令:git reset --hard HEAD~0
命令:git reset --hard HEAD~1
如图所示:
两句命令执行后,均出现了提示:
命令git reset --hard HEAD~0执行后提示为:
HEAD is now at 7cd6092 xxxxxxxxxxxxxxxxxxxxx
命令git reset --hard HEAD~1执行后提示为:
HEAD is now at 813a2a9 xxxxxxxxxxxxxxxxxxxxx
提示表示HEAD值目前位于XX版本号的版本 ,xxxxxxx为提交时编写的描述信息。我们再执行git log命令查看提交版本历史记录:
我们执行了2次命令,第一次是将当前版本回退到最新的版本(HEAD~0);第二次是将当前版本回退到上一个版本(HEAD~1)。也就是执行这两句命令后,现在的版本应处于上一个版本。
同时,我们可以看到,最新的提交版本历史记录的commit id是:813a2a9,结合执行命令前,我们使用git log查看的结果来看,正是之前我们刚进行提交操作的上一个版本。
从结果可以看出,回退版本成功了,但刚刚的提交却消失了。
我们再来查看之前修改的代码:
之前对testResetSoft方法的修改消失了,同时新增的方法也没有了。
我们再执行git status查看当前工作区的状态:
发现工作区中没有任何文件发生了变化,提示没有任何东西需要提交,工作区是干净的。也就是说,这次的版本回退,起始点后的代码都消失了。
由此我们可以得出以下结论:
使用该命令后,会将指定版本为起始点,将起始点后所有的新增或修改后的代码删除,同时删除commit和index信息。
也就是说,执行命令后,本地代码完全回到了指定版本的代码,起始点后所有的新增、修改、提交都不存在在暂存区与本地仓库中了。
所以这个命令可以说是非常危险的,它会把起始点后所有的信息都清除掉,无法找回。
故该命令谨慎使用。
git reset --mixed : 不会改变当前状态下的工作区,会保留代码,同时将指定版本后的暂存和提交均进行回退,之前已暂存的信息都会变为未暂存状态。如果需要继续暂存和提交,需要重新执行命令。
git reset --soft : 不会改变当前状态下的暂存区,会保留代码,可以根据需求进行暂存区内容调整、或继续进行提交暂存区内容到本地仓库操作。
git reset --hard : 不会保留代码,会使用指定版本的内容代码覆盖当前工作区、暂存区,相当于将指定版本后的代码最为本地最新代码。(谨慎使用)