首页 >科技周边 >IT业界 >用git撤消错误的5种方法

用git撤消错误的5种方法

Joseph Gordon-Levitt
Joseph Gordon-Levitt原创
2025-02-10 12:19:08762浏览

5 Ways to Undo Mistakes with Git

软件开发,无论经验多丰富,都难免出错。但优秀程序员与普通程序员的区别在于,他们知道如何撤销错误!

如果你使用 Git 作为版本控制系统,那么你已经拥有了一套强大的“撤销工具”。本文将向你展示五种强大的 Git 撤销错误的方法!

关键要点

  • Git 允许用户通过丢弃不需要的本地更改来撤销代码中的错误。这可以使用 git restore 命令完成,该命令会将文件重置为其最后一次提交的状态。为了更精细的控制,可以使用 -p 标志在补丁级别丢弃更改。
  • git log 命令可用于将特定文件恢复到特定版本。用户可以识别文件损坏的“错误提交”,然后使用 git checkout 命令将文件恢复到错误提交之前的版本。
  • Git 的 Reflog 工具可用于恢复丢失的版本或已删除的分支。Reflog 记录本地存储库中所有 HEAD 指针的移动,允许用户返回到以前的状态并恢复丢失的数据。
  • 用户可以使用 git cherry-pick 命令将提交移动到不同的分支。如果提交到错误的分支,用户可以检出正确的分支,将提交移动过去,然后使用 git reset 从原始分支中删除不需要的提交。

丢弃部分本地更改

编码过程通常很混乱。有时,感觉像是两步前进,一步后退。换句话说:你编写的一些代码很棒……但有些则不然。这就是 Git 可以帮助你的地方:它允许你保留好的部分,并丢弃不再需要的更改。

让我们来看一个包含一些“本地”更改(即尚未提交的更改)的示例场景。

5 Ways to Undo Mistakes with Git

注意:为了更好的概述和更清晰的可视化,我在一些屏幕截图中使用了 Tower Git 桌面客户端。你不需要 Tower 就可以学习本教程。

让我们先解决 general.css 中的问题。我们所做的更改完全朝着错误的方向发展。让我们撤销所有更改,并重新创建该文件的最后一次提交状态:

<code class="language-bash">$ git restore css/general.css</code>

请注意,或者,我也可以使用 git checkout 命令来达到相同的结果。但是因为 git checkout 有很多不同的用途和含义,所以我更倾向于使用稍微更新一些的 git restore 命令(它只专注于这些类型的任务)。

我们在 index.html 中的第二个问题有点棘手。我们在这个文件中做的一些更改实际上是很好的,而只有一部分需要撤销。

5 Ways to Undo Mistakes with Git

同样,git restore 命令可以解决问题——但这次要使用 -p 标志,因为我们要深入到“补丁”级别:

<code class="language-bash">$ git restore css/general.css</code>

然后,Git 会引导你,并询问你——对于该文件中的每一块更改——你是否要丢弃它。

5 Ways to Undo Mistakes with Git

你会注意到,我对第一块更改输入了“n”(为了保留它),对第二块更改输入了“y”(为了丢弃它)。该过程完成后,你会看到只有第一块有价值的更改保留了下来——就像我们想要的那样!

将特定文件重置为以前的状态

有时,你可能想要将特定文件恢复到特定版本。例如,你知道 index.html 在之前的某个时间点工作正常,但现在不行了。这时你想要倒退时间,但只针对这个特定文件,而不是整个项目!

我们首先需要找出我们想要恢复的哪个确切版本。使用正确的参数集,你可以让 git log 命令显示你单个文件的历史记录:

<code class="language-bash">$ git restore -p index.html</code>

5 Ways to Undo Mistakes with Git

这只会显示 index.html 被更改的提交,这对于查找导致问题出现的“坏苹果”版本非常有用。

如果你需要更多信息,并想要查看这些提交的内容,你可以让 Git 使用 -p 标志显示这些提交中的实际更改:

<code class="language-bash">$ git log -- index.html</code>

一旦我们找到了导致我们可爱的小文件损坏的错误提交,我们就可以继续修复错误了。我们将通过恢复错误提交之前版本的该文件来做到这一点!这很重要:我们不想恢复引入错误的提交中的文件,而是恢复最后一个良好状态——该提交之前的那个提交!

<code class="language-bash">$ git log -p -- index.html</code>

~1 附加到错误提交的哈希值将指示 Git 执行以下操作:转到引用的提交之前的一个版本。

执行该命令后,你会发现 index.html 在你的本地工作副本中被修改了:Git 为我们恢复了该文件的最后一个良好版本!

使用 Reflog 恢复丢失的版本

Git 急救包中的另一个强大的撤销工具是“Reflog”。你可以把它想象成一个日志,Git 在其中记录本地存储库中发生的所有 HEAD 指针移动——例如提交、检出、合并和变基、cherry-pick 和重置。所有更重要的操作都会在这里被很好地记录下来!

当然,这样的日志非常适合那些事情进展不顺利的情况。因此,让我们先制造一个小灾难——然后我们可以用 Reflog 来修复它。

假设你确信你最近的几次提交都不好:你想摆脱它们,因此使用了 git reset 来返回到之前的版本。结果,“错误”提交从你的提交历史中消失了——正如你想要的那样。

5 Ways to Undo Mistakes with Git

但正如生活有时那样,你注意到这是一个坏主意:最终,这些提交并没有那么糟糕!但坏消息是,你刚刚将它们从你的存储库的提交历史中删除了!?

5 Ways to Undo Mistakes with Git

这是 Git 的 Reflog 工具的经典案例!让我们看看它如何拯救你:

<code class="language-bash">$ git restore css/general.css</code>

5 Ways to Undo Mistakes with Git

让我们逐一分解:

  • 首先,Reflog 非常容易打开:一个简单的 git reflog 就足够了。
  • 其次,你会注意到记录的状态按时间顺序排序,最新的状态在顶部。
  • 如果你仔细观察,你会发现最顶部的(也就是最新的)项目是一个“重置”操作。这正是我们 20 秒前所做的。显然,这个日志有效?
  • 如果我们现在想要撤消我们的无意“重置”,我们可以简单地返回到之前的状态——这也在这里被很好地记录下来!我们可以简单地将该先前状态的提交哈希复制到剪贴板,然后从中开始。

为了恢复此先前状态,我们可以再次使用 git reset,或者简单地创建一个新分支:

<code class="language-bash">$ git restore -p index.html</code>

5 Ways to Undo Mistakes with Git

正如我们可以高兴地验证的那样,我们的新分支包含了我们认为通过意外的 git reset 故障而丢失的提交!

恢复已删除的分支

Reflog 也可在其他情况下派上用场。例如,当你无意中删除了一个你真的不应该删除的分支时。让我们来看一下我们的示例场景:

<code class="language-bash">$ git log -- index.html</code>

让我们假设我们的客户/团队负责人/项目经理告诉我们,我们一直在开发的漂亮的分析功能不再需要了。我们井井有条,当然会删除相应的 feature/analytics 分支!

上面你可以看到,在我们的示例场景中,我们当前检出了该分支:feature/analytics 是我们当前的 HEAD 分支。为了能够删除它,我们必须首先切换到另一个分支:

<code class="language-bash">$ git restore css/general.css</code>

Git 告诉我们我们即将做一些非常严重的事情:由于 feature/analytics 包含在其他地方不存在的唯一提交,因此删除它将破坏一些(可能是有价值的)数据。好吧……既然不再需要该功能,我们可以继续:

<code class="language-bash">$ git restore -p index.html</code>

你可能已经预料到接下来会发生什么:我们的客户/团队负责人/项目经理高兴地告诉我们,该功能又回来了!? 他们毕竟想要继续进行!?

同样,我们面临一个糟糕的情况,我们可能丢失了宝贵的数据!因此,让我们看看 Reflog 是否可以再次拯救我们:

<code class="language-bash">$ git log -- index.html</code>

5 Ways to Undo Mistakes with Git

如果你仔细观察,好消息就会显而易见。在我们(灾难性地)能够删除我们的分支之前,我们必须执行 git checkout 以切换到其他分支(因为 Git 不允许你删除当前分支)。当然,此检出也记录在 Reflog 中。为了恢复我们已删除的分支,我们现在可以简单地将之前的状态作为新分支的起点:

<code class="language-bash">$ git log -p -- index.html</code>

瞧:我们的分支起死回生了!???

如果你碰巧使用的是 Tower 等桌面 GUI,撤消此类错误通常就像按下 CMD Z 一样简单。

5 Ways to Undo Mistakes with Git

将提交移动到不同的分支

最后,让我们再来看一个“哦,不!”部门的经典案例:在错误的分支上提交。

今天,许多团队都制定了一条规则,禁止直接提交到长期分支,如“main”、“master”或“develop”。通常,新的提交应该只通过合并/变基到达这些分支。然而,我们有时会忘记并直接提交……

让我们以以下场景为例。

5 Ways to Undo Mistakes with Git

我们应该在 feature/newsletter 上提交,但无意中在 master 分支上触发了提交。让我们一步一步地看看解决方案。

首先,我们必须确保这次我们在正确的分支上,所以我们正在检出 feature/newsletter

<code class="language-bash">$ git checkout <bad-commit-hash>~1 -- index.html</bad-commit-hash></code>

现在我们可以使用 cherry-pick 命令安全地将该提交移动过去:

<code class="language-bash">$ git reflog</code>

我们可以查看 feature/newsletter,将会看到该提交现在也存在于这里。

5 Ways to Undo Mistakes with Git

到目前为止,一切顺利。但是 cherry-pick 没有从 master 分支(它永远不应该在那里)删除提交。因此,我们也必须在那里清理我们的烂摊子:

<code class="language-bash">$ git restore css/general.css</code>

我们切换回 master,然后使用 git reset 从历史记录中删除(这里)不需要的提交。

最后,一切又恢复正常了——所以你现在可以开始你的快乐舞蹈了!???

撤销错误是一种超能力

我以前说过,而且不幸的是我们都知道这是真的:我们无法避免错误!无论我们多么优秀的程序员,我们都会不时地搞砸。因此,问题不在于我们是否犯错,而在于我们如何有效地处理它们并解决问题

如果你想了解更多关于 Git 撤销工具的信息,我强烈推荐“Git 急救包”。这是一个(免费的)简短视频合集,向你展示如何在 Git 中清理和撤消错误。

祝你开发顺利,勇于尝试,当然也要善于修复!

关于使用 Git 撤销错误的常见问题解答 (FAQ)

git resetgit revert 有什么区别?

git resetgit revert 是两个帮助你撤消 Git 存储库中更改的命令,但它们的工作方式不同。git reset 将你的 HEAD 指针移动到特定的提交。这意味着它实际上“忘记”了你在重置到的提交之后的所有提交。这是一个破坏性操作,应该谨慎使用。另一方面,git revert 创建一个新的提交来撤消特定提交中所做的更改。这是一个安全的操作,因为它不会更改现有历史记录。

如何撤消 git add 操作?

如果你已经使用 git add 暂存了更改,并且想要撤消此操作,可以使用 git reset 命令。例如,如果你想要取消暂存特定文件,可以使用命令 git reset <file></file>。如果你想要取消暂存所有更改,可以使用 git reset 而不指定文件。

我可以撤消 git commit 吗?

是的,你可以使用 git resetgit revert 命令撤消 git commitgit reset 将你的 HEAD 指针移回到你想要撤消的提交之前的提交,有效地擦除不需要的提交。另一方面,git revert 将创建一个新的提交来撤消不需要的提交中所做的更改。

如何撤消特定文件中的更改?

如果你已经对特定文件进行了更改,并且想要撤消这些更改,可以使用 git checkout 命令。例如,git checkout -- <file></file> 将丢弃指定文件的本地工作目录中的更改。

git stash 是什么?

git stash 是一个允许你临时保存你不想立即提交的更改的命令。如果你需要切换到不同的分支,但不想提交当前更改,这将非常有用。你可以稍后使用 git stash apply 应用暂存的更改。

如何查看我的 Git 历史记录?

你可以使用 git log 命令查看你的 Git 历史记录。这将向你显示存储库中所有提交的列表,以及它们的提交消息。

我可以撤消 git push 吗?

是的,你可以撤消 git push,但这比撤消本地更改要复杂一些。你需要使用带有 -f--force 选项的 git push 命令来用你的本地存储库覆盖远程存储库。要小心使用此命令,因为它可能会对正在处理同一存储库的其他人员造成问题。

如何撤消多个提交?

如果你想要撤消多个提交,可以使用 git reset 命令以及 HEAD~<number></number> 语法。例如,git reset HEAD~3 将你的 HEAD 指针移回到三个提交之前。

软重置和硬重置有什么区别?

软重置将你的 HEAD 指针移动到特定的提交,但不会更改你的工作目录和暂存区。这意味着你仍然会看到来自“已忘记”提交的更改作为未提交的更改。另一方面,硬重置将丢弃工作目录和暂存区中的所有更改,有效地将你的存储库恢复到指定提交时的状态。

硬重置后我可以恢复提交吗?

是的,硬重置后可以恢复提交,但这并不简单。Git 会在 reflog 中保留所有 ref 更新(例如移动 HEAD 指针)的日志。你可以使用 git reflog 命令找到你想要恢复的提交,然后使用 git branch 在该提交处创建一个新分支。

以上是用git撤消错误的5种方法的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn