Git撤销提交:GitRevert使用技巧与场景

Git 撤销提交:Git Revert 使用技巧与场景

在 Git 的版本控制世界里,提交 (commit) 就像是给你的项目打上一个个快照。然而,有时候我们会发现之前的某个提交引入了错误,或者需要回退到之前的某个状态。这时,git revert 就成了我们的救星。

与直接删除提交历史的 git reset 不同,git revert 通过创建一个新的提交来“撤销”之前的提交,从而保留了完整的提交历史。这对于协作开发来说至关重要,因为它不会破坏其他人的工作。

本文将详细介绍 git revert 的使用技巧与各种应用场景,帮助你更好地掌握这个强大的 Git 命令。

1. git revert 的基本用法

git revert 的基本语法非常简单:

bash
git revert <commit-hash>

其中 <commit-hash> 是你要撤销的提交的哈希值。你可以通过 git log 命令查看提交历史并找到相应的哈希值。

执行 git revert 后,Git 会自动创建一个新的提交,这个新提交的内容与被撤销的提交的内容正好相反。Git 会打开一个编辑器,让你编辑提交信息。你可以使用默认的提交信息,也可以根据需要进行修改。保存并关闭编辑器后,新的提交就会被添加到你的分支历史中。

示例:

假设我们有一个提交历史如下:

```
commit d4e3c2a (HEAD -> main)
Author: John Doe john.doe@example.com
Date: Tue Oct 24 15:30:00 2023 +0800

Fix: Bug in user authentication

commit a1b2c3d
Author: John Doe john.doe@example.com
Date: Tue Oct 24 14:00:00 2023 +0800

Feat: Add user profile page

commit e5f6g7h
Author: Jane Smith jane.smith@example.com
Date: Tue Oct 24 13:00:00 2023 +0800

Initial commit

```

如果我们发现 a1b2c3d 这个提交引入了一个 bug,我们可以使用 git revert 来撤销它:

bash
git revert a1b2c3d

执行后,Git 会创建一个新的提交,内容与 a1b2c3d 相反,并打开编辑器让你编辑提交信息。默认的提交信息可能如下:

```
Revert "Feat: Add user profile page"

This reverts commit a1b2c3d.
```

保存并关闭编辑器后,提交历史会变成这样:

```
commit f8g9h0i (HEAD -> main)
Author: John Doe john.doe@example.com
Date: Tue Oct 24 15:45:00 2023 +0800

Revert "Feat: Add user profile page"

This reverts commit a1b2c3d.

commit d4e3c2a
Author: John Doe john.doe@example.com
Date: Tue Oct 24 15:30:00 2023 +0800

Fix: Bug in user authentication

commit a1b2c3d
Author: John Doe john.doe@example.com
Date: Tue Oct 24 14:00:00 2023 +0800

Feat: Add user profile page

commit e5f6g7h
Author: Jane Smith jane.smith@example.com
Date: Tue Oct 24 13:00:00 2023 +0800

Initial commit

```

可以看到,a1b2c3d 提交仍然存在,但它的更改已经被 f8g9h0i 这个新提交撤销了。

2. git revert 的常用选项

git revert 提供了一些选项,可以让你更精细地控制撤销操作:

  • -n--no-commit: 这个选项告诉 Git 不要自动创建提交。撤销操作会被暂存,你可以修改后再手动提交。这在你需要一次性撤销多个提交,或者需要对撤销后的更改进行进一步调整时非常有用。

    ```bash
    git revert -n

    ... 修改文件 ...

    git commit -m "Revert commit and fix conflicts"
    ```

  • -e--edit: 这是默认选项,允许你在提交前编辑提交信息。

  • --no-edit: 不打开编辑器,直接使用 Git 自动生成的提交信息。

  • -m parent-number--mainline parent-number: 用于撤销合并提交 (merge commit)。合并提交有两个或多个父提交,你需要指定要保留哪个父提交作为主线。parent-number 是一个数字,表示父提交的编号 (从 1 开始)。通常,1 表示合并时所在的分支,2 表示被合并的分支。

    bash
    git revert -m 1 <merge-commit-hash> # 保留当前分支的更改,撤销被合并分支的更改

    * --abort: 遇到冲突时中止revert.
    * --continue: 解决冲突后继续revert.

3. git revert 的应用场景

git revert 在以下场景中非常有用:

  • 撤销单个提交: 这是最常见的用法,用于撤销引入了错误或不需要的更改的单个提交。

  • 撤销一系列提交: 你可以使用 git revert 撤销一系列连续的提交。Git 会按照从新到旧的顺序逐个撤销这些提交。

    bash
    git revert <commit-hash-1>..<commit-hash-n>

    注意,这里的范围是左开右闭的,<commit-hash-1>不会被 revert, <commit-hash-n>会被revert.

  • 撤销合并提交: 如前所述,你可以使用 -m 选项撤销合并提交。

  • 修复公开分支上的错误: 如果你在一个公开分支 (例如 maindevelop) 上发现了一个错误,应该使用 git revert 来修复它,而不是 git reset。因为 git reset 会修改提交历史,可能会导致其他协作者遇到问题。

  • 回滚功能: 如果你发布了一个新功能,但发现它存在问题或不受用户欢迎,可以使用 git revert 来回滚这个功能。

4. 解决冲突

在执行 git revert 时,可能会遇到冲突。这通常是因为被撤销的提交和后续的提交都修改了同一部分代码。

当 Git 遇到冲突时,它会暂停撤销操作,并在受影响的文件中标记冲突。你需要手动解决这些冲突,然后使用 git add 将解决后的文件添加到暂存区,最后使用 git revert --continue 继续撤销操作,或者git revert --abort取消撤销。

解决冲突的步骤如下:

  1. 打开冲突文件: Git 会在冲突文件中使用特殊的标记来指示冲突的位置。
  2. 手动解决冲突: 你需要选择保留哪一部分代码,或者将两部分代码合并起来。
  3. 删除冲突标记: 解决完冲突后,删除 Git 添加的冲突标记。
  4. 添加到暂存区: 使用 git add 将解决后的文件添加到暂存区。
  5. 继续或中止撤销: 使用 git revert --continue 继续撤销操作, 或者git revert --abort取消撤销.

5. 与 git reset 的比较

git revertgit reset 都可以用来撤销提交,但它们的工作方式和适用场景有很大的不同:

| 特性 | git revert | git reset |
| ------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 工作方式 | 创建一个新的提交来“撤销”之前的提交,保留完整的提交历史。 | 将 HEAD 指针移动到指定的提交,可以删除之后的提交历史 (取决于使用的模式)。 |
| 提交历史 | 保留完整的提交历史。 | 可以修改提交历史 (使用 --hard 模式时)。 |
| 协作开发 | 安全,不会影响其他协作者。 | 不安全,可能会导致其他协作者遇到问题 (如果在共享分支上使用 --hard 模式)。 |
| 适用场景 | 撤销公开分支上的提交,修复错误,回滚功能。 | 撤销本地未推送的提交,整理本地提交历史,回退到之前的某个状态 (在本地分支上)。 |
| 撤销合并提交 | 需要使用 -m 选项指定主线。 | 可以直接撤销合并提交,但通常不推荐这样做,因为它会破坏合并提交的语义。 |
|回滚多个提交| 需要指定一个范围,按时间倒序依次revert. | 直接移动Head指针,一步到位. |

总结:

  • git revert 更安全,适用于公开分支和协作开发。
  • git reset 更强大,适用于本地分支和需要修改提交历史的场景。

6. 总结

git revert 是一个非常有用的 Git 命令,可以让你安全地撤销提交,同时保留完整的提交历史。掌握 git revert 的使用技巧和各种应用场景,可以帮助你更好地管理你的 Git 项目,更有效地进行协作开发。记住, git revert 总是优先于 git reset --hard 在共享分支上进行撤销操作。 通过练习和实践,你将能够熟练地使用 git revert 来应对各种版本控制挑战。

THE END