git回滚操作-reset与revert的使用与区别

594 阅读4分钟

git回滚简介

git中,回退操作总是无法完全避免的 当我们使用回退操作的时候,一般都会涉及到两个命令git resetgit revert 这两者都能实现回退的操作,但是这两条命令,还是有很大的区别的

reset 与 reset的区别

两者都可以完成git的回滚操作,但是还是有很多的区别的,最大的区别就是

  • reset 会把 commit 记录直接抹除,而 revert 会在原有基础上新添加一条记录,是单独的一条回滚commit
  • reset要慎用,revert要更加安全一些
  • reset更适合操作本地的commit记录,如果是远程的commit,那么会涉及到协作者的git记录同步的问题,比较棘手
  • revert则可以用于本地和远程

git reset

git reset [commit-id] 操作回退到对应的commit-id,它会完成把commit-id之前的所有的所有commit的记录按照对应的模式进行处理 注意(下面两段话要理解):

  • commit-id默认就是当前最近的一条commit-id,此时commit的所有记录不会更改,只会更具明命令中的模式对当前工作区与暂存区的修改做对应的操作
  • commit-id如果为非最近的一条
    • 那么首先会把 commit-id之后的所有的commit记录所有的改动都按照命令中的模式处理到暂存区与工作区
    • 再去按照命令中的模式操作当前的暂存区和工作区的内同

主要命令参数解析

git reset [--hard | --soft | --mixed(默认值)] [HEAD(默认值) | commit-id | origin/远程分支 ] [path(默认值为全部文件)]

模式(默认为--mixed)

  • --hard 回退到指定版本,工作区内容删除,暂存区内容删除
  • --soft 回退到指定版本,工作区内容保留,暂存区内容保留
  • --mixed 回退到指定版本,工作区内容保留,暂存区内容回退到工作区

下面这张图解析了每个模式下的区别

git-reset-mode.png

回退到哪个commit(默认为HEAD)

  • HEAD
    • 一个 ^ 表示往上一个版本 HEAD表示当前版本 HEAD^表示上个版本 HEAD^^ 表示上上个版本
    • ~数字数字表示往上多少个版本 HEAD^3 表示往上3个版本
  • commit-id 回退到具体的哪次commit
  • origin/远程分支 回退到与远程某个远程分支一致

git-reset-mode-HEAD.png

路径(默认是全部)

- path => 回退的内容仅限指定的文件
- 不写即为全部文件

git revert [commit-id]

同样是回滚操作,但是他会把commit-id 的内容,做恢复操作 并同时提交一条新的commit,默认的备注就是 this reverts commit xxxx ,也可以自己修改

git-revert-1.png

git-revert-2.png

git-revert-3.png

说明

  • 这样操作更加安全
  • 这样操作可以留痕
  • 这样的操作不仅适合本地的commit,也适合远程的commit

基本操作

git revert [commit-id/HEAD/commit-a^...commit-b]

  • commit-id

    • 回滚具体某个commit-id的内容
  • HEAD表示当前commit

    • 此处的HEAD的用法与上述的git reset 处的用法是一致的
    • 通过^来表示往前推一个版本的commit-id,一个^就是一个,有几个就是几个(eg HEAD^^ ,代表往前推两个版本的commit-id)
    • 通过~数字来表示往前推几个版本的commit-id(eg,HEAD~2,往前推两个版本的commit-id)
  • commit-a^...commit-b

    • 一次性把commit-acommit-b的所有记录都回滚(eg A->B->C 通过 git revert A^...C => 最终的commit为 A->B->C->revertC->revertB->revertA)
    • 上述会产生N次revert-commit,如果想就产生一次,那么使用如下
    git revert -n commit-a^...commit-c
    git commit -m 'revert commit-a to commit-c(自己写的备注)'
    
    • 注意点:(commit 顺序为 A->B->C)
      • 如果是一个个 revert,那么应该是 先 revert C,再revert B,最后再 revert A
      • 如果是三个一起 revert,那么就是 revert A^...B(从A到C),一定要注意顺序

git-revert-3个-1.png

git-revert-3个-2.png

  • 回滚Merge的commit
    • commit分两种,一种是正常的commit,还有一种是merge commit
      • 正常 commit
      • 合并 commit(merge commit)
    • 具体操作命令 git revert -m --mainline commit-id
      • --mianline 在回退的时候以哪条线为主线 ,主线代码会被保留
        • 1 -> 左侧的commit-id对应的分支为主线
        • 2 -> 右侧的commit-id对用的分支为主线
      • commit-id 对应的 merge-commit
    • 案例准备
      • 0. 分支创建两个干净的分支 A 和 C
        1. 在 A 分支提交第一条commit (内容是 新增一个 aaa.js 文件,文件内容是 console.log('aaa'))
        1. 在 A 分支提交第一条commit (内容是 新增一个 bbb.js 文件,文件内容是 console.log('bbb'))
        1. 在 C 分支提交第一条commit (内容是 新增一个 ccc.js 文件,文件内容是 console.log('ccc'))
        1. 在 C 分支提交第一条commit (内容是 新增一个 ddd.js 文件,文件内容是 console.log('ddd'))
        1. 在 C 分支中 merge A 分支
    • 案例回滚操作
      • git revert -m 1 merge-commit
        • 1 代表保留 以为 merge 左侧的 分支为主线,主线保留,其余一边的分支回滚
        • 2 代表保留 以为 merge 右侧的 分支为主线,主线保留,其余一边的分支回滚
    • 详细截图

git-revert-merge-mainline.png

git-revert-测试-1.png

git-revert-测试-2.png

git-revert-测试-3.png

git-revert-测试-4.png

参考连接