reset和revert区别:

  • reset是将HEAD向后移动了一下,而指向的那个提交变成了HEAD,之前的提交对象都还在,只是HEAD指向了其他位置;
  • revert是HEAD向后移动了一下,同时产生一个新的提交,这个提交的内容和要回滚的内容正好相反,也就是撤销要回滚的内容,HEAD指向了新的提交。

历史提交:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ git log
commit 51d6d93f0648868db3a134fd8678657f3dc328b4 (HEAD -> feature/v1, origin/feature/v1)
Author: fuyunfeng <771085570@qq.com>
Date: Tue May 20 17:56:40 2025 +0800

feat: v1_c1+1

commit fec76a70ea7318d1ab1fd2957c225c4dde821dc9 (origin/main, origin/feature/v2, origin/feature/main, feature/v2, feature/main)
Author: fuyunfeng <771085570@qq.com>
Date: Sat Apr 19 11:48:19 2025 +0800

feat: add README

commit aef28baba64ebf39389c61f9d7360bf3936cc353
Author: fuyunfeng <771085570@qq.com>
Date: Sat Apr 19 11:35:35 2025 +0800

feat: 分片上传基础版

使用reset命令,Git会把要回退版本之后的提交都丢弃删除,如果要从当前最新回退到第一次修改,那么会删除丢弃第二、三次的提交。【仅提交记录,非真正物理删除,git reflog show】
但如果只想要恢复第二次修改,却要保留第三次的提交呢?这个时候可以用revert命令,单独回滚指定的提交,不影响后续的版本。

准确来说,reset是用来”回退”版本,或者说是将最新指针”重置”到某个历史提交节点,而revert则是用来”还原”,通过一个新的提交来”回滚覆盖”某次或者某几次提交的内容。

reset

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# git reset [--soft | --mixed | --hard] [HEAD]
# --mixed 混合合并,将要重置的提交(commit)应用到本地工作区,工作区本地改动文件内容与要重置的提交合并。 默认--mixed
# --soft 软合并,重置暂存区与要重置的提交(commit)保持一致,工作区文件内容保持不变。
# --hard 强行合并,丢撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交
# [HEAD] 可以指定具体节点id,也可以HEAD^代表上一次,HEAD^^代表上上次,HEAD~n代表上n次
$ git reset --hard fec76a7
HEAD is now at fec76a7 feat: add README

$ git log
commit fec76a70ea7318d1ab1fd2957c225c4dde821dc9 (HEAD -> feature/v1, origin/main, origin/feature/v2, origin/feature/main, feature/v2, feature/main)
Author: fuyunfeng <771085570@qq.com>
Date: Sat Apr 19 11:48:19 2025 +0800

feat: add README

commit aef28baba64ebf39389c61f9d7360bf3936cc353
Author: fuyunfeng <771085570@qq.com>
Date: Sat Apr 19 11:35:35 2025 +0800

feat: 分片上传基础版

执行reset后,本地节点已经回退到指定的commit,但是远端节点还是指向原来的commit,本地落后于远端,此时如果执行git pull代码会还原到历史提交,所以需要执行push -f强制推送覆盖远端代码。

1
2
3
4
$ git push -f
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To https://github.com/author-fuyf/largeFileUpload.git
+ 51d6d93...fec76a7 feature/v1 -> feature/v1 (forced update)

revert

git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够扭转还原要被revert的内容。

revert commit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ git revert HEAD
[feature/v1 e520e3a] Revert "feat: v1_c1"
1 file changed, 2 deletions(-)

$ git log
commit e520e3a02c8e5b16e4227f27bf8aa9e20385f7e6 (HEAD -> feature/v1)
Author: fuyunfeng <771085570@qq.com>
Date: Mon May 26 20:21:00 2025 +0800

Revert "feat: v1_c1"

This reverts commit e023c99ac908e1c67c798b62955b719a3c59e3be.

commit e023c99ac908e1c67c798b62955b719a3c59e3be (origin/feature/v1)
Author: fuyunfeng <771085570@qq.com>
Date: Thu May 22 20:09:28 2025 +0800

feat: v1_c1

revert merge

1
2
3
4
# git revert -m 1 <merge commit hash> # -m 后面的是数字1, 表示要回滚的是一个merge动作且以主分支的提交为准
$ git revert -m 1 d608d2c
[feature/main 522bb48] Revert "Merge branch 'feature/v1' into feature/main"
1 file changed, 2 deletions(-)

revert merge带来的commit丢失

因为feature/v1第一次已经merge到main主分支, revert只是在主分支上提交了一次”反向修改”(一次新的commit)覆盖了之前的merge合并,后续feature/v1再次merge到主分支时,会丢失掉之前的commit,因为git会认为此前已经进行过合并,并没有变更。

物理覆盖重新提交
暴力解决方法,人工对比版本修改差异,feature分支物理拷贝,然后重新提交合并。

reset
将master分支reset到merge和revert两次提交之前的版本节点后-f强制推送覆盖,然后重新提交合并,但主分支一般会有push限制。

1
2
3
4
5
6
7
8
$ git reset --hard fec76a7
HEAD is now at fec76a7 feat: add README

$ git merge feature/v1 --no-f
Merge made by the 'ort' strategy.
frontend/src/App.vue | 2 ++
frontend/src/main.js | 2 ++
2 files changed, 4 insertions(+)

revert再revert
对revert的那次提交记录再次进行revert覆盖,相当于又回到了revert之前的版本节点,然后重新提交合并。

1
2
3
4
5
6
7
8
$ git revert 522bb48
[feature/main 146de9d] Reapply "Merge branch 'feature/v1' into feature/main"
1 file changed, 2 insertions(+)

git merge feature/v1
Merge made by the 'ort' strategy.
frontend/src/App.vue | 2 ++
1 file changed, 2 insertions(+)

sourceTree图形化操作

reset
选中要重置到的历史节点 - 右键 - 重置当前分支到此次提交
软合并 –soft
混合合并 –mixed 默认
强行合并 –hard

alt 属性文本

revert
选中要回滚的目标节点 - 右键 - 回滚提交

alt 属性文本


参考链接

[git-revert官方文档] https://git-scm.com/docs/git-revert/zh_HANS-CN
[拜托,不要再问我Git如何回滚代码] https://zhuanlan.zhihu.com/p/137856034
[菜鸟教程-git-reset] https://www.runoob.com/git/git-reset.html
[git-revert用法] https://www.cnblogs.com/0616--ataozhijia/p/3709917.html
[git-revert再merge丢失] https://blog.csdn.net/u012175512/article/details/105858132