1. 理解问题背景
git commit --amend
是一个非常实用的命令,允许我们修改最近一次提交的内容或提交信息。但有时候,我们在 amend 提交后,发现改错了,或者想回到 amend 前的状态。这就引出了一个问题:如何撤销 git commit --amend
操作?
需要注意的是,git commit --amend
并不是在原提交上修改,而是创建了一个全新的提交,替换了原来的提交。虽然我们看到的提交历史中只有一个提交,但实际上原提交已经被 Git 保留为“游离”状态,可以通过 reflog
找回。
2. 演示场景
我们先来看一个具体场景,方便后续操作说明。
假设当前分支(比如 feature1
)的提交历史如下:
$ git log
commit 400071c470b8726ba1c749c19cb6d97cff06120c (HEAD -> feature1)
Author: Amanda Viescinski <amanda@example.com>
Date: Tue Feb 27 11:30:49 2024 -0300
My original commit message
commit 290896f0e660e38ba8bbbae06670241e7a53eeb0 (origin/main, origin/HEAD, main)
Author: Amanda Viescinski <amanda@example.com>
Date: Sun Feb 18 17:43:37 2024 -0300
Initial commit
我们执行了如下 amend 操作:
$ touch script.js
$ git add .
$ git commit --amend -m "My updated commit message"
[feature1 3499867] My updated commit message
Date: Tue Feb 27 11:30:49 2024 -0300
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 demo.txt
create mode 100644 script.js
此时查看提交历史:
$ git log
commit 34998671e2b984de80fa67fd795bd3fb61db474d (HEAD -> feature1)
Author: Amanda Viescinski <amanda@example.com>
Date: Tue Feb 27 11:30:49 2024 -0300
My updated commit message
commit 290896f0e660e38ba8bbbae06670241e7a53eeb0 (origin/main, origin/HEAD, main)
Author: Amanda Viescinski <amanda@example.com>
Date: Mon Feb 26 17:43:37 2024 -0300
Initial commit
可以看到:
- 提交哈希从
400071c
变成了3499867
- 提交信息由
My original commit message
变为My updated commit message
- 多了一个
script.js
文件
现在我们想撤销这次 amend,回到 amend 前的状态。
3. 撤销 Git Amend 的方法
3.1 查找原提交记录
我们可以通过 git reflog
查看 HEAD 指针的历史变化:
$ git reflog
3499867 (HEAD -> feature1) HEAD@{0}: commit (amend): My updated commit message
400071c HEAD@{1}: commit: My original commit message
...
其中:
HEAD@{0}
是 amend 后的提交HEAD@{1}
是 amend 前的原始提交
因此,我们可以通过重置到 HEAD@{1}
来撤销 amend。
3.2 保留修改内容撤销 amend
如果我们希望撤销 amend,但保留其中的修改内容(比如新增的 script.js
),可以使用以下命令:
$ git reset --soft HEAD@{1}
效果如下:
- 提交历史回到 amend 前的状态
- 修改内容被保留在暂存区,可以再次提交
验证:
$ git status
On branch feature1
Changes to be committed:
(use "git restore --staged ..." to unstage)
new file: script.js
3.3 删除修改内容撤销 amend
如果我们不仅想撤销 amend,还想彻底删除其中的修改内容,可以使用:
$ git reset --hard HEAD@{1}
效果如下:
- 提交历史回到 amend 前的状态
- 所有修改内容都被删除,工作区和暂存区都为空
验证:
$ git status
On branch feature1
nothing to commit, working tree clean
4. 总结
操作 | 是否保留修改内容 | 命令 |
---|---|---|
保留修改撤销 amend | ✅ | git reset --soft HEAD@{1} |
删除修改撤销 amend | ❌ | git reset --hard HEAD@{1} |
📌 小贴士:
HEAD@{1}
表示 HEAD 指针在执行git commit --amend
前指向的提交- 使用
git reflog
可以找回被删除或修改的提交 --soft
和--hard
的区别在于是否保留修改内容
✅ 推荐做法: 如果不确定是否需要保留修改,建议先使用 --soft
撤销,确认无误后再决定是否提交或删除内容。
⚠️ 注意: 如果你已经将 amend 后的提交推送到远程仓库,撤销操作后需要强制推送(git push -f
),这可能会影响其他协作者,请谨慎操作。