如何丢弃不需要的 Git 提交

GitGitBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本教程中,我们将探索不同的方法来丢弃不需要的 Git 提交,并保持提交历史的干净和有序。无论你是需要删除特定的提交、撤销一系列更改,还是压缩多个提交,我们都能满足你的需求。在本指南结束时,你将对如何有效地管理你的 Git 仓库并使其保持原始状态有深入的了解。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL git(("Git")) -.-> git/DataManagementGroup(["Data Management"]) git(("Git")) -.-> git/BranchManagementGroup(["Branch Management"]) git/DataManagementGroup -.-> git/reset("Undo Changes") git/DataManagementGroup -.-> git/restore("Revert Files") git/BranchManagementGroup -.-> git/reflog("Log Ref Changes") git/BranchManagementGroup -.-> git/rebase("Reapply Commits") subgraph Lab Skills git/reset -.-> lab-393041{{"如何丢弃不需要的 Git 提交"}} git/restore -.-> lab-393041{{"如何丢弃不需要的 Git 提交"}} git/reflog -.-> lab-393041{{"如何丢弃不需要的 Git 提交"}} git/rebase -.-> lab-393041{{"如何丢弃不需要的 Git 提交"}} end

理解 Git 提交

Git 是一个分布式版本控制系统,它允许开发者随时间追踪其代码库中的更改。Git 的核心概念是提交,它代表项目文件在特定时间点的一个快照。

Git 仓库中的每个提交都有一个唯一标识符,称为提交哈希,它是由字母和数字组成的序列,唯一地标识该提交。提交被链接在一起形成线性历史,其中每个提交都指向前一个提交,从而创建一个更改链。

graph LR A[初始提交] --> B[第二次提交] B --> C[第三次提交] C --> D[第四次提交]

Git 中的提交是不可变的,这意味着一旦创建了提交,其内容就不能更改。但是,你可以创建新的提交来撤销或修改先前的提交,从而有效地重写提交历史。

理解 Git 提交的工作原理对于管理项目历史以及与其他开发者协作至关重要。通过学习有效地丢弃、撤销和压缩提交,你可以维护一个干净且有序的 Git 仓库,从而更轻松地追踪更改、调试问题以及与团队协作。

识别不需要的提交

在 Git 仓库中识别不需要的提交是维护干净且有序的项目历史的一项重要技能。不需要的提交可能有多种形式,例如:

  • 包含不正确或不完整更改的提交
  • 引入错误或回归问题的提交
  • 包含敏感信息(如密码或 API 密钥)的提交
  • 属于某个实验性或已废弃功能的一部分的提交

要识别不需要的提交,你可以使用以下 Git 命令:

  1. git log:此命令显示仓库的提交历史。你可以使用各种选项来过滤输出,例如 --oneline 以获取简洁视图,或 --stat 以查看每个提交中更改的文件。
git log --oneline
  1. git diff:此命令显示两个提交之间或工作目录与某个提交之间的差异。你可以使用它来查看特定提交引入的更改。
git diff HEAD~1 HEAD
  1. git show:此命令显示特定提交引入的更改。你可以使用它来查看提交的详细信息,如作者、日期和文件更改。
git show HEAD

通过仔细查看提交历史以及每个提交引入的更改,你可以识别并标记任何需要丢弃或修改的不需要的提交。

使用 Git Reset 丢弃提交

git reset 命令是在 Git 仓库中丢弃不需要的提交的强大工具。它允许你将分支指针移动到特定提交,从而有效地丢弃该点之后的所有提交。

git reset 命令有三种主要模式:

  1. 软重置:此模式将分支指针移动到指定提交,但保持工作目录和暂存区不变。当你想丢弃提交但保留工作目录中的更改时,这很有用。
git reset --soft HEAD~1
  1. 混合重置:这是 git reset 的默认模式。它将分支指针移动到指定提交,将暂存区重置为与指定提交匹配,但保持工作目录不变。当你想丢弃提交并取消暂存更改,但保留工作目录中的更改时,这很有用。
git reset HEAD~1
  1. 硬重置:此模式将分支指针移动到指定提交,重置暂存区,并丢弃工作目录中的所有更改。这是最具破坏性的模式,应谨慎使用,因为它将永久删除任何未提交的更改。
git reset --hard HEAD~1

需要注意的是,git reset 命令会修改提交历史,如果你已经将提交推送到远程仓库,这可能会有问题。在这种情况下,通常最好使用 git revert 命令,它会创建一个新提交来撤销不需要的提交引入的更改。

使用 Git Revert 撤销提交

虽然 git reset 对于丢弃本地提交很有用,但如果你已经将提交推送到远程仓库,它可能会有问题。在这种情况下,通常最好使用 git revert 命令,它会创建一个新提交来撤销不需要的提交所引入的更改。

git revert 命令通过创建一个新提交来撤销指定提交中所做的更改。这样可以保留提交历史,并且便于与可能已经拉取了不需要的提交的其他开发者协作。

以下是如何使用 git revert 来撤销上一次提交所引入的更改的示例:

git revert HEAD

这将创建一个新提交来撤销上一次提交中所做的更改。如果你想撤销特定的提交,可以指定提交哈希而不是 HEAD

git revert 1234567

如果撤销提交所引入的更改与仓库的当前状态之间存在冲突,Git 会要求你在完成撤销操作之前解决冲突。

使用 git revert 而不是 git reset 的一个优点是它保留了提交历史,使得更容易理解项目的演变。然而,git revert 可能会创建额外的提交,这可能会使提交历史更加复杂。在某些情况下,使用 git reset 来丢弃尚未推送到远程仓库的本地提交可能更合适。

使用 Git Rebase 压缩提交

除了丢弃单个提交外,Git 还提供了一种将多个提交合并或“压缩”为单个提交的方法。这称为“变基”,使用 git rebase 命令执行。

git rebase 命令允许你通过在新的基础提交之上应用一系列提交来重写提交历史。当你有一系列小的、增量的提交,并且想将它们合并为一个更有意义的提交时,这会很有用。

以下是如何将最后三个提交压缩为一个提交的示例:

git rebase -i HEAD~3

这将打开一个交互式变基编辑器,你可以在其中指定如何修改最后三个提交。你会看到类似这样的内容:

pick 1234567 提交 1
pick 2345678 提交 2
pick 3456789 提交 3

要压缩提交,对于你想要合并的提交,可以将 pick 命令更改为 squash(或简称为 s):

pick 1234567 提交 1
squash 2345678 提交 2
squash 3456789 提交 3

保存并关闭编辑器后,Git 会将这三个提交合并为一个提交,并且你将能够编辑新的压缩提交的提交消息。

需要注意的是,变基会修改提交历史,如果你已经将提交推送到远程仓库,这可能会有问题。在这种情况下,通常最好使用 git merge 命令,它会保留原始的提交历史。

恢复已删除的提交

在某些情况下,你可能会意外删除一个提交,之后才意识到它很重要。幸运的是,Git 提供了一种恢复这些已删除提交的方法。

Git 维护着一个引用日志(reflog),它记录了对仓库分支引用(如 HEAD 和分支名称)所做的所有更改。只要引用日志没有被清理或过期,就可以用它来恢复已删除的提交。

要查看引用日志,可以使用 git reflog 命令:

git reflog

这将显示对仓库分支引用所做的所有更改的列表,包括任何已删除的提交。

要恢复已删除的提交,可以使用 git reset 命令,并结合引用日志中适当的提交哈希或引用。例如,如果你想恢复哈希为 1234567 的提交,可以使用以下命令:

git reset 1234567

这会将当前分支指针移回到已删除的提交,从而有效地将其恢复到仓库中。

需要注意的是,引用日志只在有限的时间内跟踪更改(默认情况下通常是 30 天)。如果你试图恢复已从引用日志中清理的提交,可能无法恢复它。

为防止意外丢失重要提交,定期将你的更改推送到远程仓库是个好习惯。这将确保即使你意外删除或修改了本地提交,你的提交历史也能得到保留。

总结

对于任何使用版本控制的开发者来说,丢弃不需要的 Git 提交都是一项必不可少的技能。在本全面教程中,你已经学习了各种根据需要识别、丢弃和恢复提交的技术。通过掌握这些 Git 命令,你可以保持仓库的有序性,简化开发工作流程,并确保提交历史干净且易于维护。请记住,有效管理 Git 提交的能力是一项宝贵的资产,在你的整个编程旅程中都会对你有很大帮助。