Git | git revert命令详解

关注:CodingTechWork

引言

Git 是一个强大的版本控制工具,广泛应用于现代软件开发中。它为开发人员提供了多种功能来管理代码、协作开发和版本控制。在 Git 中,有时我们需要撤销或回退某些提交,而git revert 是一个非常有用的命令。与git reset等命令不同,git revert能够通过创建新的提交 来撤销历史提交,保证项目历史的完整性。

在本篇文章中,我们将详细介绍 Git 中 git revert 的使用方式、工作原理、实战示例以及一些注意事项。

git revert介绍

git revert用于撤销一个已经提交到 Git 仓库的更改。不同于git resetgit revert会通过创建一个新的提交"反转"指定提交的内容,而不会改变历史提交的记录。因此,git revert 是一种更安全的回退操作,适用于团队合作中,因为它不会影响历史提交的结构。

git revert 的工作原理

git revert原理:

  1. 生成新的提交git revert 会创建一个新的提交,内容是要撤销的提交的"反操作"。也就是说,git revert 会通过相反的改动 来撤销指定提交的更改。例如,如果原来提交中增加了某些代码行,git revert会通过删除这些行来撤销该提交。
  2. 保持项目历史的完整性 :与git reset可能修改项目历史不同,git revert不会删除任何提交,而是通过新的提交来记录撤销操作,从而保证了版本历史的完整性。这使得它特别适用于公共分支(如 mastermain 分支)。

执行步骤

  1. Git 会根据指定的提交,计算出需要反向操作的更改。
  2. 创建一个新的提交,将这些反向更改应用到当前工作区。
  3. 你可以选择是否修改提交信息(默认信息为"Revert ")。
  4. 提交反向更改,新的提交将插入到当前分支历史中。

git revert 的常见用法

撤销单个提交

假设我们在分支上做了多次提交,其中有一个提交包含了不需要的更改。使用 git log 查看提交历史:

bash 复制代码
git log --oneline

输出结果可能是这样的:

a1b2c3d (HEAD -> master) Added new feature
a1342cf Fixed bug in feature X
d4e5f6g Added README file

如果你想撤销某个特定提交,可以直接指定该提交的哈希值(commit hash)来执行git revert

bash 复制代码
git revert <commit-hash>

例如,如果你想撤销提交 a1b2c3d,可以运行以下命令:

bash 复制代码
git revert a1b2c3d

Git 会自动生成一个新的提交,反向应用 a1b2c3d 提交中的修改,并提示你输入提交消息。

撤销多个提交

如果你需要撤销一系列提交,可以使用 git revert-n--no-commit选项,它会将所有反向更改暂时保存在暂存区中,但不会立即提交。你可以手动编辑这些更改,并最终一起提交。

bash 复制代码
git revert -n <commit-hash1>^..<commit-hash2>
  • <commit-hash1>^..<commit-hash2> 表示从 <commit-hash1> <commit-hash2> 的提交范围。
  • ^表示选择 <commit-hash1> 的父提交,因此是一个范围。
    举个例子,撤销从提交 a1b2c3d 到提交 d4e5f6g 的所有修改:
bash 复制代码
git revert -n a1b2c3d^..d4e5f6g

执行后,所有变更会暂时存放在暂存区,等待提交。

举个例子:

假设你有以下的提交历史:

* abc1234 (HEAD -> master) Merge feature-branch into master
* d7e6b2d (feature-branch) Add new feature
* 3a6c0f2 (master) Initial commit

其中,abc1234 是一个合并提交,feature-branch 被合并进了 master。现在,你想撤销这个合并提交,并希望保留 master 分支的变更,因此使用命令:

bash 复制代码
git revert -m 1 abc1234

这个命令会创建一个新的提交,撤销合并操作中的更改,实际上它将会 恢复到 abc1234 合并之前的状态,但历史记录仍会保留合并提交。新的提交将会与 abc1234 之后的提交一起继续保留在历史中。
为什么需要 -m 参数?

合并提交有多个父提交,Git 需要知道你希望保留哪个父提交的内容。-m 1表示选择第一个父提交作为保留的版本,通常是主分支的版本。如果你使用 -m ,那么 Git 将选择第二个父提交,通常是被合并进来的分支的版本。

使用交互式 git revert

当你想撤销多个提交时,有时会遇到冲突,Git 会提示你进行冲突解决。git revert 会一个一个地撤销指定的提交,并且如果有冲突,Git 会停止并让你解决冲突。解决冲突后,你可以继续操作。

解决冲突后运行:

bash 复制代码
git revert --continue

如果你决定取消当前的撤销操作,可以使用:

bash 复制代码
git revert --abort

撤销合并提交

有时,你可能会遇到需要撤销合并提交的场景。合并提交具有特殊的结构,因此在执行 git revert 时需要额外小心。假设你有一个合并提交 abc1234,可以使用以下命令来撤销它:

bash 复制代码
git revert -m 1 abc1234

-m 1: 指定了合并提交的"主父提交"(通常是主分支)。-m后面的数字表示选择哪个父提交作为保留版本。

通过 git revert -m,Git 会根据指定的父提交创建一个新的提交来撤销合并操作。

强制跳过某次提交的提交信息编辑

在某些场景下,你可能希望跳过git revert操作中的提交信息编辑过程。可以通过--no-edit选项来跳过:

bash 复制代码
git revert --no-edit f7e8b2c

这个命令会直接执行`git revert操作,但不会弹出编辑器让你修改提交信息,而是使用默认的信息。

实战示例:撤销错误提交

假设你正在一个开发分支feature/login上工作,发现最近的一个提交引入了一个错误。你需要撤销该错误提交,但又不想修改历史提交(即不使用 git reset)。这时,git revert就非常适合。

查看提交历史

首先,我们查看最近的提交历史,找到要撤销的提交。

bash 复制代码
git log --oneline

输出可能是这样的:

a1b2c3d Add login feature
d4e5f6g Fix UI bug
h7i8j9k Update documentation

假设提交 a1b2c3d 引入了一个错误,我们需要撤销它。

执行 git revert

接下来,使用 git revert 撤销该提交:

bash 复制代码
git revert a1b2c3d

Git 会自动生成一个新的提交,撤销 a1b2c3d 中的所有更改。

解决冲突

如果 Git 在应用反向更改时发生了冲突,Git 会提示你进行冲突解决。你需要打开冲突文件,手动解决冲突,然后执行:

bash 复制代码
git add <conflicted-file>
git revert --continue

完成提交

最终,提交就会成功创建,撤销操作也完成了。可以通过 git log 查看新的提交记录,确认撤销操作已经生效。

bash 复制代码
git log --oneline

输出可能是:

f7g8h9i Revert "Add login feature"
a1b2c3d Add login feature
d4e5f6g Fix UI bug
h7i8j9k Update documentation

着重讲一下git revert -m

git提交历史模拟

假设我们有以下的 Git 历史:

* abc1234 (HEAD -> master) Merge feat02-branch into master
* def5678 (feat02-branch) Add feature 2
* ghi2345 (feat01-branch) Add feature 1
* jkl3456 (master) Initial commit

在这个例子中:

  • abc1234 是合并提交,它将 feat02-branch 合并到 master。
  • def5678 是 feat02-branch 上的提交,它增加了 feat02-branch 的功能。
  • ghi2345 是 feat01-branch 上的提交,它增加了 feat01-branch 的功能。
  • jkl3456 是 master 上的初始提交。

合并提交 abc1234 是一个合并提交,它有两个父提交:

  1. jkl3456(master 分支的提交)
  2. def5678(feat02-branch 分支的提交)

git revert -m 1 abc1234

git revert -m 1 abc1234表示撤销合并提交 abc1234,并保留第一个父提交(master 分支的提交)。即,撤销 feat02-branch 的更改并保留 master 分支的更改。

执行这个命令后,Git 会生成一个新的提交,撤销合并 feat02-branch 到 master 的操作,而不影响 feat01-branch 和 master 之间的关系。
命令

bash 复制代码
git revert -m 1 abc1234

git revert -m 2 abc1234

git revert -m 2 abc1234 表示撤销合并提交 abc1234,并保留第二个父提交(feat02-branch 分支的提交)。即,撤销 master 上的更改并保留 feat02-branch 的更改。

执行这个命令后,Git 会生成一个新的提交,撤销 master 分支的更改,同时保留 feat02-branch 的更改。
命令

bash 复制代码
git revert -m 2 abc1234

git revert -m 3 abc1234

git revert -m 3是一个特殊情况,适用于三方合并,通常会有多个父提交。例如,如果合并提交涉及 feat01-branch、feat02-branch 和 master 三个分支,那么可以使用 -m 3 来指定第三个父提交。然而,在我们这个例子中,由于合并提交 abc1234 只涉及 master 和 feat02-branch 两个父提交,因此 -m 3 不适用。假设有三方合并的历史如下:

bash 复制代码
*   abcd1234 (HEAD -> master) Merge branch 'feat01-branch' and 'feat02-branch'
|\
| * 12345678 (feat01-branch) Commit in feat01-branch
* | 87654321 (feat02-branch) Commit in feat02-branch
|/
*   11223344 Initial commit in master

在这个示例中:

  • abcd1234 是合并提交,具有 3 个父提交:
    • 父提交 1:master(在 abcd1234 之前的提交)。
    • 父提交 2:feat01-branch(合并进来的一个分支)。
    • 父提交 3:feat02-branch(合并进来的另一个分支)。

git revert -m 3 abcd1234使用-m 3时,Git 会选择第三个父提交作为基准(在这个例子中是 feat02-branch),并撤销合并提交中的更改。也就是说,撤销的合并提交会回滚 master 和 feat01-branch 的更改,但保留 feat02-branch 上的内容。

bash 复制代码
git revert -m 3 abcd1234

效果:Git 会撤销 abcd1234 的合并,回滚 master 和 feat01-branch 上的修改。结果是保留了 feat02-branch 上的修改,并回滚了 master 和 feat01-branch 的修改。

-m 总结

  • git revert -m 1 <commit>:撤销合并提交,保留第一个父提交的变更。
  • git revert -m 2 <commit>:撤销合并提交,保留第二个父提交的变更。
  • git revert -m 3 <commit>:撤销合并提交,保留第三个父提交的变更(适用于三方合并)。

git revert 与 git reset 的比较

git revert vs git reset

git revert

  • 用于撤销已经提交的内容。
  • 保持历史提交的完整性,不会改变提交记录。
  • 适用于公共分支,避免影响其他开发人员的工作。

git reset

  • 用于重置当前分支的指针,可以回退到某个历史提交。
  • 会改变提交历史,可能导致丢失更改。
  • 适用于个人分支或本地仓库的操作。

哪个更适合团队合作?

在团队协作中,通常建议使用git revert,因为它不会重写历史,而是创建一个新的提交,撤销先前的更改。这样可以保证团队成员之间的协作历史不受干扰。

注意事项

  1. 小心使用git revertgit revert会创建新的提交,因此如果你频繁地进行撤销操作,可能会导致提交历史变得冗长。在撤销多个提交时,可以考虑将多个撤销操作合并到一次提交中,以保持清晰的历史记录。
  2. 处理冲突:当你撤销提交时,可能会遇到文件冲突。务必认真解决冲突,以确保撤销操作正确执行。
  3. 避免在已经发布的分支中使用 git resetgit reset会重写历史,这会给协作带来麻烦,而git revert保持了历史的连贯性,因此在公共分支中,推荐使用git revert

总结

git revert是 Git 中撤销历史提交的强大工具,能够通过创建新的提交来撤销指定的更改,保持项目历史的完整性,避免重写历史,适用于团队合作中的常见场景。通过理解和掌握git revert,开发人员可以更加灵活和安全地管理代码历史,并在出现错误时轻松回退。

相关推荐
李狗蛋儿啊1 小时前
zero自动化框架搭建---Git安装详解
运维·git·自动化
人工干智能4 小时前
科普:“git“与“github“
git·github
{⌐■_■}16 小时前
【git】提交修改、回撤、回滚、Tag 操作讲解,与reset (--soft、--mixed、--hard) 的区别
大数据·git·elasticsearch
GardenTu18 小时前
初尝git自结命令大全与需要理解的地方记录
git·github
真就死难1 天前
Git是什么
git
机械心1 天前
代码管理git详细使用教程及最佳实践路径
git
hkj88081 天前
Git 常用命令
git
dawnkylin2 天前
通过 fork 为项目做出贡献
git·github
1379003402 天前
Git 设置代理
git
xiaodunmeng2 天前
sourcetree gitee 详细使用
git