git思维结构及git reset , git revert区别
项目不尽人意,需要进行回滚,遇到了这两位,遂做随笔记录
在回滚基础上,首先我们应该明确的是git 的“三棵树结构”
想直接了解区别请下滑
三棵树分别是:HEAD,Index,Working Directory
1.HEAD
HEAD 是一个指针,它总是指向该分支上的最后一次提交
你可以理解为,你最后一次commit文件的那次,文件是什么样,HEAD就是指的那次的文件状态
2.Index
索引,官方解释是:预期的下一次提交
说人话:你的暂存区
那些你在工作区进行过的任何修改,都可以提交到暂存区里
3.Working Directory
你的工作区,你可以在这里进行任意的代码编写工作
git的工作流程
首先我们进入到一个新的本地文件中进行代码编写,我们把他记做V1
使用命令 git init来进行git 仓库初始化,即这个文件开始进入到git仓库之中
文件就处于工作区之中
现在我们觉得代码编写的不错,想进行进一步的保存
使用命令 git add 文件名 来进行文件的修改的暂存
此时文件被复制了一份到暂存区之中
进一步的,我们觉得这次的修改通过,想把他永久性地保存和记录
使用命令 git commit 来进行提交到本地的git仓库里
此时HEAD就会指向本次提交的文件
这就是文件从修改到提交的整个过程
进一步,我们继续进行文件编码工作,完善功能
因此文件从v1变为了v2
然后我们想保存整个修改,重复上面的步骤
git add 和 git commit
这里主要看git仓库的变化,你存在本地的v1版本仍然是存在的,并且HEAD又原来指向V1向后移动,指向了你最新提交的V2
这就是HEAD的含义:总是指向你最后一次提交的文件快照
接下来我们进行第三次的修改 文件变为V3且进行暂存和提交

接下来我们分别看看三个命令是如何进行工作的(本质上来看)
- git reset
git reset命令后面有多种参数可以进行选择
git reset首先都是移动 HEAD 的指向,将HEAD移动到对应的曾经本地的文件快照上,接着进行的动作和输入的参数有关
当使用的是 reset --soft
它将仅仅让HEAD停在我们之前的文件上,也就是只改变HEAD树的内容,其他不变
它本质上是撤销了上一次 git commit 命令。 当你在运行 git commit 时,Git 会创建一个新的提交,并移动 HEAD 所指向的分支来使其指向该提交。 当你将它 reset 回 HEAD~(HEAD 的父结点)时,其实就是把该分支移动回原来的位置,而不会改变索引和工作目录。
当使用的是 reset --mixed
它将不仅仅使HEAD变为之前的版本,index区域的内容也会恢复到之前的版本
它依然会撤销一上次 提交,但还会 取消暂存 所有的东西。 于是,我们回滚到了所有 git add 和 git commit 的命令执行之前。
当使用的是 reset --hard
你撤销了最后的提交、git add 和 git commit 命令 以及 工作目录中的所有工作。
警告:–hard 标记是 reset 命令唯一的危险用法,它也是 Git 会真正地销毁数据的仅有的几个操作之一。 其他任何形式的 reset 调用都可以轻松撤消,但是 --hard 选项不能,因为它强制覆盖了工作目录中的文件。 在这种特殊情况下,我们的 Git 数据库中的一个提交内还留有该文件的 v3 版本, 我们可以通过 reflog 来找回它。但是若该文件还未提交,Git 仍会覆盖它从而导致无法恢复。
- git revert
使用git revert 可以同样实现文件的版本回滚,并且会更加的温和
推荐当我们已经推送到远程仓库后想回滚,使用该方法
git revert 的本质是,它是一次新的提交
而只是本次提交修改的内容是我们想回退到的那个版本的内容
就像是将那个版本的内容进行git pull 下拉
然后由你来决定哪些地方保留新的哪些保留旧的
比如上面的例子,我们做了V1,V2,V3三个版本进行了提交
但是我们的V2里面是存在代码错误的,这个时候我们想进行回滚到V1版本,对比来分析git reset和git revert
当我们使用git reset来回滚到V1 那么相当于我们V2,V3所做的所有的操作都将被取消,这时往往会遗失一些重要的东西,因为我们在V2,V3编码的时候并不是所有的代码都是无效的需要删除的
以及我们如果在V2,V3创建了其他的分支的话均会消失
就感觉reset是一个非常强硬的方法
他会给你直接还原到你想去的那个版本,完完全全的还原,不多不少
而当我们使用git revert来进行回滚的话,他相当于一次全新的提交
撤销了V2的,并且V3的修改都会进行保留
然后类似git pull的时候
让你来进行冲突代码的处理,你自己决定哪些需要保留哪些删除
非常的温和
git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。
补充:使用git reset 和git revert还原版本的流程:
二者都很相似
前置知识点:每次我们进行commit提交的时候,都会记录在git log中,并且每次的commit 都会自动生成一个commitID
1.使用git log来查看日志
你们会看到自己提交的记录以及对应提交的commitID
按q退出(这个知识点困惑了好多人!)
2.使用git reset或者git revert commitID来进行回滚