git-版本回滚git reset --soft、--mixed、--hard

1、场景需求

某开发团队的A同学,工作积极性很高,已进入公司就开始进入工作状态,一天内就提交了很8次代码,但是当下午在和开发组长汇报工作的时候,发现在第4次提交代码后,由于业务需求不明,导致后续4次的提交都是有问题的。
这个时候,A同学就遇到了一个问题,我想要将已经提交过的多次记录给取消掉。
像这种多次commit取消的效果,其实有个专业术语,叫"版本回滚",版本回滚主要说的是对于已经提交的动作,进行撤销的动作,由于该动作涉及到的对象是仓库,在这里我们可以基于git reset命令来完成我们的目标。

2、reset原理

2.1、流程图

2.2、原理说明

git reset的提交流程可以理解为多次git rm。
reset执行前: A版本经过commit
+b.txt 后到达B版本,在经过commit +c.txt 后到达C版本
reset执行后: C版本经过rm
-c.txt 和 -b.txt后到达A版本
注意: 通过图示,可以看出来git reset有强制更新代码或者删除分支权限git reset会将commit记录删除掉

3、git reset命令解析

3.1、命令格式

命令格式:git help reset
git reset [-q] [<tree-ish>] [--] <paths>...
git reset (--patch | -p) [<tree-sh>] [--] [<paths>...]
git reset [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit_id>]
该命令是对本地仓库的项目进行回滚操作的命令,它主要有如下几个参数
--soft # 缓存区和工作目录都不会被改变,只是本地库中的文件回滚到当时的那个版本 --mixed # 默认选项。缓存区和你指定的提交同步(被清空),但工作目录不受影响 --hard # 缓存区和工作目录都同步到你指定的提交,该选项非常危险
注意:这三个参数的区别点就是:我修改的内容需不需要保留的问题,作用范围如下

3.2、--soft、--mixed、--hard作用域图

4、--soft、--mixed、--hard-实践

4.1、准备环境

# 我们基于一个空的仓库,创建一个存在多次commit的效果: A-->B-->C
mkdir /data/reset -p && cd /data/reset
git init
echo first  >a.txt;git add a.txt;git commit -m "A"
echo second >b.txt;git add b.txt;git commit -m "B"
echo second >c.txt;git add c.txt;git commit -m "C"

4.2、--hard-实践

# --hard是一种代码仓库完整回滚的一种效果,能力还是相当的强。
# 缓存区和工作目录都同步到你指定的提交,该选项非常危险

# 当前效果示例
root@localhost:/data/reset#  git log --pretty=format:"%h - %an, %ar : %s" --graph
* 1b42d7c - 277667028@qq.com, 4 minutes ago : C
* 222eb7c - 277667028@qq.com, 4 minutes ago : B
* bd39d33 - 277667028@qq.com, 4 minutes ago : A

# 向工作目录和暂存区中都增加一些内容
echo 'reset' > reset.txt
git add reset.txt 
echo 'reset1' > reset1.txt
git status

# --hard 回滚到版本号为B
git reset --hard 222eb7c
git status

root@localhost:/data/reset# ll
drwxr-xr-x 8 root root 4096 Jun 11 04:04 .git/
-rw-r--r-- 1 root root    6 Jun 11 03:57 a.txt
-rw-r--r-- 1 root root    7 Jun 11 03:58 b.txt
-rw-r--r-- 1 root root    7 Jun 11 04:03 reset1.txt
root@localhost:/data/reset# git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        reset1.txt

nothing added to commit but untracked files present (use "git add" to track)

#可以看到:除了未加入到git代码管理系统的文件,其他(工作目录、暂存区、本地仓库)都回滚到了B版本的效果,但是未被跟踪的文件是不会被管理起来的

4.3、--soft-实践

# --soft参数它只是将本地库中的文件回滚,其他两个位置不受影响
# 在版本B的基础上,给工作目录和暂存区增加一些文件
git add reset1.txt 
echo 'reset' > reset.txt
git status

# --soft回滚到版本号为A
git reset --soft bd39d33

# git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   b.txt
        new file:   reset1.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        reset.txt

# ll
drwxr-xr-x 8 root root 4096 Jun 11 04:08 .git/
-rw-r--r-- 1 root root    6 Jun 11 03:57 a.txt
-rw-r--r-- 1 root root    7 Jun 11 03:58 b.txt
-rw-r--r-- 1 root root    6 Jun 11 04:08 reset.txt
-rw-r--r-- 1 root root    7 Jun 11 04:03 reset1.txt

# 可以看到:除了本地仓库中B的文件被退回到暂存区之外,其他都没有任何变化,即只有代码仓库文件被回滚了

4.4、--mixed-实践

# --mixed参数是默认选项。缓存区和你指定的提交同步(被清空),但工作目录不受影响
#在--soft实践的基础上,重新提交一次,并给暂存区增加一个文件
git add .
git commit -m "D"
echo d > d.txt
git add d.txt 
git status

# 查看当前提交状况
# git log --pretty=format:"%h - %an, %ar : %s" --graph
* 9af9d00 - 277667028@qq.com, 12 seconds ago : D
* bd39d33 - 277667028@qq.com, 14 minutes ago : A

# --mixed 回滚到版本号为A 
git reset --mixed bd39d33
# ll
drwxr-xr-x 8 root root 4096 Jun 11 04:11 .git/
-rw-r--r-- 1 root root    6 Jun 11 03:57 a.txt
-rw-r--r-- 1 root root    7 Jun 11 03:58 b.txt
-rw-r--r-- 1 root root    2 Jun 11 04:10 d.txt
-rw-r--r-- 1 root root    6 Jun 11 04:08 reset.txt
-rw-r--r-- 1 root root    7 Jun 11 04:03 reset1.txt

# git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        b.txt
        d.txt
        reset.txt
        reset1.txt

nothing added to commit but untracked files present (use "git add" to track)

# 可以看到:D版本提交的内容和当时暂存区的内容,统统都发生了回滚,都变成了未跟踪状态了

 

posted @ 2023-06-11 12:14  小粉优化大师  阅读(44)  评论(0编辑  收藏  举报