git revert
示例及其与 git reset
的区别
git revert
和 git reset
都是用于撤销更改的 Git 命令,但它们的目的和行为有显著区别:
-
git revert
:通过创建新提交,撤销指定提交的更改,不会影响提交历史。 -
git reset
:直接修改分支的提交历史,可以回滚到某个提交,并重置提交记录、暂存区和工作区。
以下是详细的介绍和示例。
一、git revert
示例
git revert
用于撤销指定的提交,通过追加一个新的提交来抵消之前的更改。它非常适合在协作环境中使用,因为它不会修改提交历史,从而避免影响其他开发者的工作。
1. 单个提交的撤销
假设你的提交历史如下:
$ git log --oneline
c5d3a2b (HEAD -> main) Fix critical bug
a1b2c3d Add new feature
9f8e7g6 Initial commit
现在发现最新的提交 c5d3a2b
有问题,需要撤销。
操作:
git revert c5d3a2b
执行后,Git 会打开一个编辑器,提示输入新提交的消息。你可以直接保存或修改提交信息。
结果:
$ git log --oneline
e4f7h8i Revert "Fix critical bug"
c5d3a2b Fix critical bug
a1b2c3d Add new feature
9f8e7g6 Initial commit
解释:
-
git revert
创建了一个新的提交e4f7h8i
,用来撤销c5d3a2b
的更改。 - 原提交
c5d3a2b
仍然保留在提交历史中,没有被删除。
2. 撤销多个提交
如果你想一次撤销多个提交,可以使用 -n
(或 --no-commit
)选项,先将所有撤销的更改放入暂存区,然后再一次性提交。
操作:
git revert --no-commit c5d3a2b a1b2c3d
git commit -m "Revert multiple commits"
结果:
$ git log --oneline
d4f5g6h Revert multiple commits
c5d3a2b Fix critical bug
a1b2c3d Add new feature
9f8e7g6 Initial commit
3. 撤销一个合并提交
如果需要撤销一个合并提交,需要使用 -m
选项指定要保留的父分支。
假设提交历史如下:
$ git log --oneline --graph
* 3a5b6c7 (HEAD -> main) Merge branch 'feature'
|\
| * 1a2b3c4 Add feature A
|/
* 9f8e7g6 Initial commit
要撤销合并提交 3a5b6c7
,执行:
git revert -m 1 3a5b6c7
解释:
-
-m 1
表示选择第一个父分支(通常是主分支main
)作为保留的分支。 - 这将创建一个新的提交,撤销合并的更改,但保留主分支的内容。
二、git reset
示例
git reset
用于直接回退到某个提交,可以选择性地影响提交记录、暂存区和工作区。它通常用于修改本地历史,不适合协作环境中使用。
1. 回退到上一个提交
假设提交历史如下:
$ git log --oneline
c5d3a2b (HEAD -> main) Fix critical bug
a1b2c3d Add new feature
9f8e7g6 Initial commit
要回退到 a1b2c3d
:
git reset --hard a1b2c3d
结果:
$ git log --oneline
a1b2c3d Add new feature
9f8e7g6 Initial commit
解释:
-
c5d3a2b
被删除,分支直接回退到了a1b2c3d
。 - 使用
--hard
,暂存区和工作区的更改也会被丢弃。
2. 仅重置暂存区
如果只想取消暂存区的更改,而保留工作区的文件:
git reset --mixed HEAD~1
解释:
- 提交记录回退到上一个提交(
HEAD~1
)。 - 暂存区被清空,但工作区的更改仍然保留。
3. 取消最近一次的 git add
操作
如果不小心把某些文件添加到了暂存区,可以通过 git reset
将它们移回工作区:
git reset example.txt
解释:
- 文件
example.txt
被移出暂存区,但工作区中的更改不会丢失。
三、git revert
与 git reset
的区别
特性 |
|
|
提交历史 | 创建一个新的提交,保留原有历史 | 修改提交历史,可能会删除部分提交 |
协作环境 | 安全,适合共享分支 | 不安全,可能影响其他开发者的工作 |
操作范围 | 撤销指定的某一提交或多个提交 | 回滚到某个提交,清除之后的提交记录 |
暂存区和工作区 | 不会清除暂存区和工作区的内容 | 根据选项( |
撤销合并 | 支持,需指定父分支( | 不支持直接撤销合并 |
使用场景 | 撤销错误提交,同时保留提交历史 | 回滚本地历史,清理提交记录 |
四、总结:如何选择?
- 使用
git revert
的场景:
- 在协作环境中撤销错误提交。
- 不想改变提交历史,确保分支历史清晰可追溯。
- 撤销合并提交。
- 使用
git reset
的场景:
- 本地开发时,需要回滚到某个状态。
- 清理本地历史,不打算与其他人共享分支。
- 撤销未提交的更改或已暂存的更改。
五、注意事项
-
git reset --hard
是危险操作,可能导致数据丢失。在执行前,确认是否有需要保存的更改。 -
git revert
不会丢失数据,它通过新增提交实现撤销,适合在共享分支中使用。