如何撤销 Git 提交但保留更改

GitGitBeginner
立即练习

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

简介

在本全面指南中,你将学习如何撤销 Git 提交,同时保留你的更改。无论你在提交中犯了错误,还是需要重新组织提交历史记录,本教程都将为你提供有效管理 Git 仓库所需的工具和技术。从撤销最新提交到还原特定提交,你将全面了解如何撤销 Git 提交但保留更改。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL git(("Git")) -.-> git/BasicOperationsGroup(["Basic Operations"]) git(("Git")) -.-> git/DataManagementGroup(["Data Management"]) git(("Git")) -.-> git/BranchManagementGroup(["Branch Management"]) git/BasicOperationsGroup -.-> git/commit("Create Commit") git/DataManagementGroup -.-> git/reset("Undo Changes") git/DataManagementGroup -.-> git/restore("Revert Files") git/BranchManagementGroup -.-> git/merge("Merge Histories") git/BranchManagementGroup -.-> git/log("Show Commits") git/BranchManagementGroup -.-> git/reflog("Log Ref Changes") git/BranchManagementGroup -.-> git/cherry_pick("Cherry Pick") git/BranchManagementGroup -.-> git/rebase("Reapply Commits") subgraph Lab Skills git/commit -.-> lab-392512{{"如何撤销 Git 提交但保留更改"}} git/reset -.-> lab-392512{{"如何撤销 Git 提交但保留更改"}} git/restore -.-> lab-392512{{"如何撤销 Git 提交但保留更改"}} git/merge -.-> lab-392512{{"如何撤销 Git 提交但保留更改"}} git/log -.-> lab-392512{{"如何撤销 Git 提交但保留更改"}} git/reflog -.-> lab-392512{{"如何撤销 Git 提交但保留更改"}} git/cherry_pick -.-> lab-392512{{"如何撤销 Git 提交但保留更改"}} git/rebase -.-> lab-392512{{"如何撤销 Git 提交但保留更改"}} end

理解 Git 提交

Git 是一个分布式版本控制系统,它允许开发者随时间追踪其代码库的变更。Git 的核心概念是提交,它代表了项目在特定时间点的一个快照。理解 Git 提交的工作原理对于有效管理项目历史记录以及在必要时撤销变更至关重要。

什么是 Git 提交?

Git 提交是对你仓库中文件所做更改的记录。当你对文件进行更改并决定保存这些更改时,你就创建了一个新的提交。每个提交包含以下信息:

  1. 唯一标识符:每个提交都被分配一个唯一的 SHA-1 哈希值,用作其标识符。
  2. 作者:做出更改并创建提交的人。
  3. 时间戳:创建提交的日期和时间。
  4. 提交消息:对提交中所做更改的简要描述。
  5. 文件快照:提交时仓库中所有文件的完整状态。

提交历史和分支

随着你继续处理项目,你会创建多个提交,形成一个线性的变更历史。Git 还允许你创建分支,分支是独立的开发线路,可以从主代码库分叉出来。每个分支都有自己的提交历史,根据需要可以合并回主分支或其他分支。

graph LR A[初始提交] --> B[提交 2] B --> C[提交 3] C --> D[提交 4] A --> E[功能分支] E --> F[提交 5] F --> G[提交 6]

理解你的 Git 仓库的提交历史和分支结构对于导航和管理项目的演变至关重要。

提交的最佳实践

为了有效地使用 Git 提交,遵循一些最佳实践很重要:

  1. 编写有意义的提交消息:提供清晰简洁的提交消息,描述提交中所做的更改。
  2. 保持提交小而专注:提交逻辑相关的更改,并且在必要时能够轻松理解和撤销。
  3. 避免提交敏感信息:确保你不会意外地将任何敏感数据(如密码或 API 密钥)提交到你的仓库。
  4. 定期推送到远程仓库:定期将你的本地提交推送到远程仓库,如 GitHub 或 GitLab,以确保你的工作得到备份并且团队成员可以访问。

通过理解 Git 提交的基本原理,你将更有能力管理项目历史记录、与他人协作以及在必要时撤销更改。

识别提交问题和错误

在使用 Git 时,你可能会遇到与提交相关的各种问题和错误。了解如何识别这些问题是解决它们的第一步。

常见的提交问题

你可能遇到的一些最常见的与提交相关的问题包括:

  1. 意外提交:你可能会意外提交了你不打算提交的更改,或者你可能忘记在提交中包含重要的更改。
  2. 提交消息不正确:提交消息可能无法准确反映提交中所做的更改,这使得难以理解提交的目的。
  3. 提交中包含敏感信息:你可能意外提交了敏感信息,如密码或 API 密钥,这些不应存储在你的仓库中。
  4. 合并冲突:在合并分支时,你可能会遇到冲突,即 Git 无法自动解决不同分支中所做更改之间的差异。
  5. 提交作者信息不正确:提交可能是由错误的作者做出的,或者作者信息可能不正确。

识别提交问题

要识别与提交相关的问题,你可以使用以下 Git 命令:

  1. git status:此命令显示你的工作目录和暂存区的当前状态,帮助你识别任何未提交的更改。
  2. git log:此命令显示提交历史记录,包括提交消息、作者和时间戳,使你能够查看你的提交历史。
  3. git diff:此命令显示你的工作目录、暂存区和上一次提交之间的差异,帮助你识别尚未提交的更改。
  4. git show <提交哈希>:此命令显示特定提交引入的更改,这对于调查提交的内容很有用。

通过使用这些命令,你可以快速识别并解决与你的 Git 提交相关的任何问题或错误。

撤销最新提交

如果你进行了一次想要撤销的提交,有几种不同的方法来完成这项任务。你选择的方法将取决于你是想完全丢弃该提交还是将更改保留在工作目录中。

丢弃最新提交

要完全丢弃最新提交并将其从提交历史记录中删除,你可以使用带有 --hard 选项的 git reset 命令:

git reset --hard HEAD~1

此命令将:

  1. 将当前分支指针向后移动一个提交,有效地撤销最新提交。
  2. 丢弃在已撤销提交中所做的所有更改,将你的工作目录重置为与上一次提交的状态匹配。

运行此命令后,最新提交将从你的提交历史记录中删除,并且你的工作目录将更新为与上一次提交匹配。

保留最新提交中的更改

如果你想撤销提交但将更改保留在工作目录中,可以使用带有 --soft 选项的 git reset 命令:

git reset --soft HEAD~1

此命令将:

  1. 将当前分支指针向后移动一个提交,有效地撤销最新提交。
  2. 将已撤销提交中的更改保留在你的工作目录中,允许你进行其他更改或创建新的提交。

运行此命令后,最新提交将从你的提交历史记录中删除,但更改仍将存在于你的工作目录中,供你进一步修改。

请记住,撤销提交是一项强大的操作,所以务必谨慎,确保你不会意外丢弃重要工作。在运行这些命令之前和之后,始终要仔细检查你的仓库状态。

恢复未提交的更改

有时,你可能对文件进行了更改,但尚未将其提交到 Git 仓库。如果你需要丢弃这些未提交的更改,可以使用 git checkout 命令将工作目录恢复到上次提交时的状态。

丢弃所有未提交的更改

要丢弃工作目录中所有未提交的更改,请使用以下命令:

git checkout.

此命令将:

  1. 将工作目录中所有修改的文件恢复到上次提交时的状态。
  2. 从工作目录中删除任何未跟踪的文件(即不属于你的 Git 仓库的文件)。

运行此命令后,你的工作目录将恢复到上次提交时的状态,任何未提交的更改都将被丢弃。

丢弃特定文件的更改

如果你只想丢弃特定文件的更改,可以使用以下命令:

git checkout -- <file1> <file2>... <fileN>

<file1><file2> 等替换为你要丢弃更改的文件路径。此命令将把指定的文件恢复到上次提交时的状态,而其余的工作目录保持不变。

恢复已删除的文件

如果你不小心从工作目录中删除了一个文件,可以使用 git checkout 命令恢复它:

git checkout -- <已删除的文件>

此命令将从上次提交中恢复已删除的文件,并将其带回你的工作目录。

请记住,git checkout 命令是将工作目录恢复到已知状态的强大工具。但是,务必谨慎使用,因为如果使用不当,可能会丢弃重要的更改。

回滚特定提交

在某些情况下,你可能需要撤销特定提交所引入的更改,同时保留其余的提交历史记录。这可以使用 git revert 命令来实现。

理解 Git Revert

git revert 命令会创建一个新的提交,该提交会撤销指定提交所引入的更改。这与 git reset 不同,后者只是从历史记录中删除提交。

当你运行 git revert 时,Git 会:

  1. 创建一个新的提交,该提交会撤销指定提交中所做的更改。
  2. 将新的“回滚”提交添加到你的提交历史记录中。

当你想要撤销一个提交,但仍保留其余的提交历史记录时,这种方法很有用。

回滚特定提交

要回滚特定提交,你可以使用以下命令:

git revert <提交哈希>

<提交哈希> 替换为你想要回滚的提交的 SHA-1 哈希。例如:

git revert 1234567890abcdef

此命令将:

  1. 创建一个新的提交,该提交会撤销指定提交中所做的更改。
  2. 将新的“回滚”提交添加到你的提交历史记录中。

运行此命令后,你的提交历史记录将如下所示:

graph LR A[初始提交] --> B[提交 2] B --> C[提交 3] C --> D[提交 4] D --> E[回滚提交 4]

在此示例中,“回滚提交 4”提交会撤销提交 4 中所做的更改,同时保留其余的提交历史记录。

处理合并冲突

如果回滚提交所引入的更改与仓库中的其他更改发生冲突,Git 会提示你解决合并冲突。然后,你可以使用标准的 Git 冲突解决技术来处理冲突并完成回滚操作。

通过使用 git revert,你可以撤销特定提交所引入的更改,同时保持提交历史记录的清晰和可理解。

修改最新提交

有时,你可能需要对最新提交进行更改,比如修正提交消息或添加遗漏的更改。Git 提供了 git commit --amend 命令来让你修改最新提交。

修改提交消息

要更改最新提交的提交消息,你可以使用以下命令:

git commit --amend -m "新的提交消息"

此命令将:

  1. 打开你的默认文本编辑器,以便你编辑提交消息。
  2. 使用更新后的消息创建一个新提交,替换之前的提交。

运行此命令后,提交历史将使用新的提交消息进行更新,并且之前的提交将被替换。

修改提交内容

如果你在最新提交中遗漏了一些更改,可以修改提交以包含这些更改:

  1. 进行你想要包含在提交中的其他更改。

  2. 使用 git add 暂存这些更改。

  3. 运行以下命令来修改提交:

    git commit --amend

    此命令将:

    • 打开你的默认文本编辑器,如果你愿意,可以编辑提交消息。
    • 将新更改包含在修改后的提交中,替换之前的提交。

运行此命令后,提交历史将使用修改后的提交进行更新,该提交现在包含了额外的更改。

修改提交时的注意事项

需要注意的是,修改提交可能会有影响,特别是如果该提交已经被推送到远程仓库。修改提交实际上会创建一个新提交,这意味着提交的 SHA-1 哈希将改变。如果其他团队成员已经基于原始提交开展了工作,这可能会导致问题。

因此,通常建议仅修改尚未推送到远程仓库的提交,或者在修改已经共享的提交之前与你的团队进行沟通。

通过使用 git commit --amend 命令,你可以轻松纠正错误或向最新提交添加遗漏的更改,帮助你维护一个干净且准确的提交历史。

重置到之前的提交

在某些情况下,你可能需要丢弃多个提交并将仓库重置到之前的状态。Git 提供了 git reset 命令来帮助你实现这一点。

理解 Git 重置

git reset 命令允许你将当前分支指针移动到指定的提交,从而有效地撤销该提交之后的所有提交。然而,了解 git reset 的不同模式很重要,因为它们会对你的工作目录和提交历史产生不同的影响。

软重置

git reset--soft 选项将分支指针移动到指定的提交,但它会使你的工作目录和暂存区保持不变。这意味着已撤销提交所引入的更改仍存在于你的工作目录中,你可以选择创建一个新提交或继续处理这些更改。

git reset --soft <提交哈希>

混合重置(默认)

git reset 的默认模式是 --mixed 选项,它将分支指针移动到指定的提交,并取消为下一次提交暂存的任何更改。不过,更改仍存在于你的工作目录中,允许你根据需要进行查看和重新暂存。

git reset <提交哈希>

硬重置

git reset--hard 选项将分支指针移动到指定的提交,并丢弃你的工作目录和暂存区中的所有更改。这有效地将你的仓库重置到指定提交的状态,丢弃所有后续更改。

git reset --hard <提交哈希>

重置到特定提交

要将你的仓库重置到之前的提交,你可以使用带有适当选项的 git reset 命令:

  1. 软重置:
    git reset --soft <提交哈希>
  2. 混合重置(默认):
    git reset <提交哈希>
  3. 硬重置:
    git reset --hard <提交哈希>

<提交哈希> 替换为你要重置到的提交的 SHA-1 哈希。

使用 git reset 时要谨慎,因为如果使用不当,它可能会潜在地丢弃重要工作。在运行这些命令之前和之后,始终要查看你的仓库状态,以确保你不会丢失任何有价值的更改。

解决合并冲突

当你在 Git 中合并分支时,可能会出现两个分支中同一行代码都被修改的情况,从而导致合并冲突。解决这些冲突是每个 Git 用户必备的技能。

理解合并冲突

当 Git 无法自动协调正在合并的两个分支中所做的更改时,就会发生合并冲突。这通常发生在两个分支中同一行代码都被修改,而 Git 无法确定哪些更改应优先采用的情况下。

当发生合并冲突时,Git 会在你的文件中标记出冲突部分,你需要通过选择保留哪些更改来手动解决冲突。

识别合并冲突

在尝试合并两个分支后,你可以通过运行 git status 命令来识别合并冲突。Git 会列出有合并冲突的文件,然后你可以打开这些文件来解决冲突。

git status

这将输出类似以下内容:

未合并的文件:
  (使用 "git add <文件>..." 标记已解决)
    修改:file1.txt
    修改:file2.txt

解决合并冲突

要解决合并冲突,请按以下步骤操作:

  1. 在文本编辑器中打开冲突文件。

  2. 找到 Git 添加的冲突标记,其看起来如下:

    <<<<<<< HEAD
    ## 你的更改
    =======
    ## 来自另一个分支的更改
    >>>>>>> 另一个分支
  3. 决定你要保留哪些更改,并删除冲突标记和你不想要的更改。

  4. 保存文件。

  5. 使用 git add 将已解决的文件添加到暂存区。

  6. 对所有冲突文件重复步骤 1 - 5。

  7. 所有冲突解决后,运行 git commit 完成合并。

使用 LabEx 工具解决冲突

LabEx 提供了一套工具,可以帮助你更高效地解决合并冲突。例如,LabEx 合并工具允许你直观地比较冲突更改,并轻松选择你要保留的更改。

通过了解如何识别和解决合并冲突,你将更有能力管理基于 Git 的项目的协作性质,并维护一个干净、一致的提交历史记录。

撤销提交的最佳实践

撤销提交是 Git 中的一项强大功能,但谨慎使用以避免意外后果非常重要。以下是撤销提交时需要牢记的一些最佳实践:

了解影响

在撤销提交之前,确保你理解即将采取的操作的影响。根据你使用的方法(例如 git resetgit revertgit commit --amend),撤销提交可能会产生不同的效果,为你的特定用例选择正确的方法很重要。

与团队沟通

如果你正在处理一个协作项目,在撤销已经推送到远程仓库的提交之前,与你的团队进行沟通至关重要。撤销提交可能会打乱其他团队成员的工作流程,因此协调你的操作以避免冲突和混乱很重要。

保持提交历史记录清晰

在撤销提交时,尽量保持你的提交历史记录清晰且易于理解。避免创建不必要的“回滚”提交或使你的仓库处于不稳定状态。使用适当的命令(git revertgit reset 等)来确保你的提交历史记录保持清晰简洁。

推送更改前进行测试

在将更改推送到远程仓库之前,确保彻底测试你的工作,以确保你没有引入任何回归问题或意外的副作用。在撤销提交时这一点尤其重要,因为你希望确信你引入的更改是正确的,并且不会给你的团队带来问题。

使用 Git 别名提高效率

为了使撤销提交更高效,可以考虑为你最常用的命令创建 Git 别名。例如,你可以为 git reset --soft HEAD~1 创建一个别名,以便快速撤销最新提交而不丢弃你的更改。

备份你的仓库

作为一般的最佳实践,定期备份你的 Git 仓库总是一个好主意,要么推送到远程服务器,要么创建本地备份。这可以帮助你在撤销提交时从意外的数据丢失或错误中恢复。

通过遵循这些最佳实践,你可以有效地管理你的 Git 提交历史记录并撤销更改,而不会对你的团队造成干扰或在你的代码库中引入新问题。

总结与更多资源

在本指南中,我们探讨了使用 Git 提交的基本概念和最佳实践。通过了解如何识别、撤销和管理你的提交历史记录,你可以有效地与团队协作,维护一个干净且有条理的代码库,并在必要时从错误中恢复。

关键要点

  • Git 提交是项目历史的构建块,代表特定时间点代码库的快照。
  • 识别并解决与提交相关的问题,如意外提交或敏感信息,对于维护健康的仓库至关重要。
  • 撤销提交,无论是最新的提交还是过去的特定提交,可以使用各种 Git 命令来实现,如 git resetgit revertgit commit --amend
  • 解决分支合并期间出现的合并冲突是与团队协作的一项基本技能。
  • 遵循最佳实践,如与团队沟通和保持干净的提交历史记录,可以帮助你有效地管理 Git 仓库。

更多资源

如果你希望加深对 Git 和版本控制的理解,以下是一些可能对你有帮助的额外资源:

请记住,掌握 Git 是一个持续的过程,你练习得越多,就会变得越得心应手和熟练。编码愉快!

总结

在本教程结束时,你将扎实掌握在保留更改的同时撤销 Git 提交的各种方法。你将能够识别并解决提交问题、恢复未提交的更改、回退特定提交、修改最新提交以及将仓库重置到之前的状态。此外,你还将学习撤销提交的最佳实践,以维护干净且有条理的 Git 历史记录。有了这些知识,你将有能力掌控自己的 Git 工作流程,并确保获得无缝的开发体验。