revert 命令会在历史中增加一条commit
记录,用来撤销之前的commit
提交记录。
对比回退的命令:amend、revert、reset
- git commit -amend:新的提交覆盖上次提交的内容
- git revert:新增一个提交记录commit,用来撤销之前的commit
- git reset:直接回退到指定的commit历史,不会新增提交记录。包括3中模式
- —soft:只回退本地仓库的代码,工作区和暂存区的内容不回退
- —mixed:回退本地仓库和暂存区,工作区的内容不回退
- —hard:工作区、暂存区、本地仓库都进行回退。
- git restore .:撤销工作区的内容修改
revert命令的使用
新建一个测试代码git仓库,提交记录如下;
shuais-MacBook-Pro:revert shuai$ git alog
* ec2ab45 (HEAD -> master) v4 w
* 00e34c1 v3 w
* cb4a3c0 v2
* 6988773 v1
v3和v4中存在错误,需要进行回退操作。
此时head指针在v4,即ec2ab45的commit上。需要把head指向v2即可达到目的。
根据之前的reset,可以很容易操作
git reset --hard ec2ab45
但是这样存在弊端,会把v3和v4的提交给隐藏掉,如果有天突然觉得v3和v4版本是正确的需要恢复,就不那么容易操作,【当然也可通过reflog可以查看,然后恢复】。 由于会撤销掉一些commit记录,很多公司是禁止使用reset命令。这时就必须是revert。
git revert commit-id
# 撤销v4提交记录,然后会出现一个编辑文本框,如下面编辑框
shuais-MacBook-Pro:revert shuai$ git revert ec2ab45
[master cf8a19a] Revert "v4 w"
1 file changed, 1 insertion(+), 2 deletions(-)
# 撤销v3提交记录,然后会出现一个编辑文本框,如下面编辑框
shuais-MacBook-Pro:revert shuai$ git revert 00e34c1
[master 1788aaa] Revert "v3 w"
1 file changed, 1 insertion(+), 2 deletions(-)
# 查看历史,可以看到新增了revert v4和revert v3
shuais-MacBook-Pro:revert shuai$ git log --oneline
1788aaa (HEAD -> master) Revert "v3 w"
cf8a19a Revert "v4 w"
ec2ab45 v4 w
00e34c1 v3 w
cb4a3c0 v2
6988773 v1
revert命令后的编辑弹出框,可以进行编辑后保存。
Revert "v3 w"
This reverts commit 00e34c14551df71df0bed4278947f33ba97aca67.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Changes to be committed:
# modified: readme.txt
revert命令的作用是通过创建一个新的版本commit,来回退到目标版本,HEAD指针指向了新生成的commit,而不是原来的目标commit。
对比revert和reset的示意图
revert时需要注意:
- 工作区或者暂存区存在修改内容未提交,则会提示先提交或者存储起来
- 在移除过程中出现冲突,先解决冲突
- 使用git add命令添加修改的冲突文件到暂存区,使用git revert —continue 来继续操作
- 如果要放弃revert,可以使用git revert —abort命令来停止移除操作,恢复到执行git revert命令之前的状态。
- 也可以使用git revert —skip命令跳过commit,该条commit将会在历史记录中被删除。这个命令也谨慎使用
工作中常用:
- git revert HEAD:撤销前一次的commit
git revert HEAD^ :撤销前前一次的commit
一次移除多个记录
在上面的例子中,只是回退了2次,如果需要进行多次回退的话
第一种方式:git revert
,顺序是从后向前,否次会多次冲突。 - 第二种方式:git revert
… ,该操作只是回退了5和6,不包括开头的4。并且要注意中间是3个点 - 第三种方式:git revert
^.. , 该操作回退了4、5、6三个提交记录。中间使用2个点。 revert常用的参数
-n
参数:--no-commit
移除多次提交记录的修改,但是不使用还原后的提交创建新的任何提交,还原只是修改工作树和索引。 ```git查看提交历史,此时还包含错误的提交代码
shuais-MacBook-Pro:revert shuai$ git log —oneline
- ec2ab45 (HEAD -> master) v4 w
- 00e34c1 v3 w
- cb4a3c0 v2
- 6988773 v1
回退v3和v4的提交
shuais-MacBook-Pro:revert shuai$ git revert -n 00e34c1^..ec2ab45
查看提交历史,v3和v4仍然存在,但是内容已经被恢复掉
shuais-MacBook-Pro:revert shuai$ git log —oneline
- ec2ab45 (HEAD -> master) v4 w
- 00e34c1 v3 w
- cb4a3c0 v2
- 6988773 v1
因为merge操作有2个分支,而revert不知道要还原哪个分支的提交。<a name="vlW2G"></a>
##### -m参数:
移除merge修改的内容。`-m parent-number`全称:`--mainline parent-number`<br />命令: `git revert [-m parent-number] <commit-id>`<br />如果需要还原的提交是merge操作,直接使用`git revert <commit-id>`是不行的,会提示我们
```git
error:commit... is a merge but no -m option was given.
fatal: revert failed
需要使用-m 1
参数来告诉revert命令哪个是主线,选择主线就还原非主线,选择非主线就还原主线。
可以使用git show命令查看commit提交记录,如果是普通commit记录,会显示这个commit的id、作者、日期、备注、更改文件的内容。如果是merge记录,则会显示merge的commit-id,备注、日期和merge的主线和合并过来的id。 ```bash commit 00e34c14551df71df0bed4278947f33ba97aca67 Merge: 6988773a8 cb4a3c01de Author: unknown test@163.com Date: Sun Jul 19 11:34:21 2020 +0800
Merge branch ‘dev’ into main
上面第二行代码显示merge的记录,说明6988773a8是主线的id,编号就是1,cb4a3c01de就是非主线的id,编号是2.需要把合并过来的分支的修改给还原掉,那么就可指定1为主线,还原掉2的提交记录。
<a name="eEP7X"></a>
### 多个回退实际操作
假如git [commit](https://so.csdn.net/so/search?q=commit&spm=1001.2101.3001.7020) 链是<br />A -> B -> C -> D<br />如果想把B,C,D都给revert,除了一个一个revert之外,还可以使用range revert<br />git revert B^..D 等价于 git revert A...D
> 用法:
> B^..D代表区间[B,D],包括B也包括D,其中B提交在前,D提交在后,D为起点commit。
> A...D 代表一个左开右闭区间(A,D],不包括A,包括D. 其中D为起点commit,A为终点commit的下一个commit
> 注意⚠️:都是闭区间时,中间2个点。前开后闭时,中间有3个点。
这样就把B,C,D都给revert了,变成:<br />A-> B ->C -> D -> D'-> C' -> B'<br />用法就是:<br />git revert BEFORE_COMMIT^..AFTER_COMMIT<br />如果我们想把这三个revert不自动生成三个新的commit,而是用一个commit完成,可以这样:<br />git revert -n BEFORE_COMMIT^..AFTER_COMMIT<br />git commit -m "revert BEFORE_COMMIT to AFTER_COMMIT"
```git
# 查看提交记录,回退到v2的commit中
shuais-MacBook-Pro:restore shuai$ git alog
* d513690 (HEAD -> master) v5
* 093b730 v4
* 4cff528 v3
* bdaa5d3 v2
* 2688ed0 v1
#下面两种方法,都是要把先有的commit放在前面。
# 第一种方法:两头都是闭区间,2个commit都会包含进去
git revert bdaa5d3^..d513690
# 第二中方法,开头是开区间,不被包含。
git revert 2688ed0...d513690
# 如果一个一个撤销的话,需要把后提交的commit放在前,这样减少冲突.
git revert d513690 093b730 4cff528 bdaa5d3