在使用 Git 时,您可能需要编辑提交信息来修正拼写错误、移除敏感信息或补充遗漏的细节。
本指南说明了如何更改最近一次提交的信息,如何通过交互式变基来改写更早的提交,以及当提交已经推送到远程仓库时应该怎么做。
快速参考
| 任务 | 命令 |
|---|---|
| 修改最近一次提交的信息 | git commit --amend -m "新信息" |
| 不修改信息,仅追加暂存更改 | git commit --amend --no-edit |
| 打开编辑器修改最近一次提交 | git commit --amend |
| 强制推送已修改的提交 | git push --force-with-lease origin branch |
| 针对更早的提交进行交互式变基 | git rebase -i HEAD~N |
如需可打印的快速参考,请参阅 Git 备忘单。
更改最近一次提交的信息
git commit --amend 命令会用新信息重写最近的提交。修改后的提交是一个全新的 Git 对象,具有不同的 SHA;原始提交在当前分支上不再存在。
如果该提交尚未推送到远程仓库,修改它是安全且简单的。
在终端中导航到仓库目录。
运行以下命令来重写最新提交的信息:
终端git commit --amend -m "新提交信息。"-m选项允许您直接在命令行上写入新信息,而无需打开编辑器。要打开默认编辑器,请运行不带-m的git commit --amend。如果您还想包含忘记暂存的更改,请在修改前添加它们:
终端git add forgotten-file.txt git commit --amend -m "新提交信息。"
推送后更改提交信息
Git 无法在远程仓库中就地编辑提交。要更改已推送提交的信息,您需要在本地重写它,然后用重写后的历史替换远程分支。这可能会给基于原始提交开展工作的人带来问题,因此在共享分支上操作之前,请咨询您的团队。
修改最近一次已推送提交的信息:
终端git commit --amend -m "新提交信息。"强制推送以更新远程仓库历史:
终端git push --force-with-lease <remote> <branch>使用
--force-with-lease而不是--force。如果自上次拉取以来有人推送到远程分支,它会拒绝覆盖,从而避免意外丢弃他人的工作。
如果要修复的提交不是最近一次的,适用相同的规则:按如下所述在本地使用交互式变基进行改写,然后强制推送该分支。
不更改信息而添加暂存的更改
要通过添加暂存的更改来修改最近一次提交,而不修改提交信息,请使用 --no-edit:
git add forgotten-file.txt
git commit --amend --no-edit这会用新文件更新提交,同时保持原始信息不变。
更改更早的或多个提交信息
要更改更早的提交或一次更改多个提交的信息,请使用交互式变基。
警告变基会重写提交历史。未经团队协调,请勿变基已推送到共享远程仓库的提交。导航到包含要更改提交的仓库。
为最后
终端N个提交启动交互式变基。例如,处理最后五个提交:git rebase -i HEAD~5Git 会在您的默认文本编辑器中打开最后 N 个提交:
纯文本pick 43f8707f9 fix: update dependency json5 to ^2.1.1 pick cea1fb88a fix: update dependency verdaccio to ^4.3.3 pick aa540c364 fix: update dependency webpack-dev-server to ^3.8.2 pick c5e078656 chore: update dependency flow-bin to ^0.109.0 pick 11ce0ab34 fix: Fix spelling. # Rebase 7e59e8ead..11ce0ab34 onto 7e59e8ead (5 commands)在每行要更改信息的提交前,将
纯文本pick替换为reword:reword 43f8707f9 fix: update dependency json5 to ^2.1.1 reword cea1fb88a fix: update dependency verdaccio to ^4.3.3 pick aa540c364 fix: update dependency webpack-dev-server to ^3.8.2 pick c5e078656 chore: update dependency flow-bin to ^0.109.0 pick 11ce0ab34 fix: Fix spelling. # Rebase 7e59e8ead..11ce0ab34 onto 7e59e8ead (5 commands)保存文件并关闭编辑器。
对于每个标记为
纯文本reword的提交,Git 都会打开一个新的编辑器窗口。编辑信息,保存并关闭:fix: update dependency json5 to ^2.1.1所有信息更新后,将更改强制推送到远程仓库:
终端git push --force-with-lease <remote> <branch>
故障排除
强制推送被拒绝,提示“stale info”
当远程分支与您的远程跟踪引用中的值不匹配时,git push --force-with-lease 会中止并显示 ! [rejected] main -> main (stale info)。这通常意味着其他人推送到该分支了。在决定如何处理之前,先获取并检查新的提交:
git fetch origin
git log --oneline HEAD..origin/main在决定如何处理这些提交之前,请勿再次推送。如果它们必须保留,请从获取的远程历史开始,在那里重复交互式变基,以便原始提交被改写,新提交在其后重放。不要简单地将修改后的提交变基到 origin/main 上,因为 Git 可能会将仅更改信息的提交识别为重复补丁而将其丢弃。如果不确定,请与贡献者协调,而不是强制推送。
Git 打开了 Vim,您无法退出
Git 从 GIT_EDITOR、core.editor、VISUAL 或 EDITOR 中选择提交信息编辑器。交互式变基可以使用单独的 GIT_SEQUENCE_EDITOR 或 sequence.editor 设置来处理其待办列表。在许多 Unix 系统上,Git 会回退到 Vi。要保存并退出 Vim 或 Vi,请按 Esc,输入 :wq,然后按 Enter。要将 Nano 设为 Git 的默认编辑器:
git config --global core.editor "nano"变基失败,提示“invalid upstream”HEAD~5 是 HEAD 的第五个第一父级祖先,因此只有当该路径至少包含六个提交(包括 HEAD)时才存在。当浅克隆不包含所需的祖先时,也可能出现同样的错误。直接检查该修订版本:
git rev-parse --verify HEAD~5如果命令失败,请降低数字。要将第一个提交包含在变基中,请使用:
终端git rebase -i --root您错误地开始了变基
取消它并将分支恢复到原来的状态:
git rebase --abort如果 Git 回答 fatal: no rebase in progress,则变基已经完成,因此没有可取消的内容。
您修改了错误的提交并丢失了原始信息
原始提交通常会在 reflog 中保留,直到不可达条目过期,默认情况下为 30 天。找到确切的条目并显示其信息,而不移动分支:
git reflog
git show -s --format=%B <old-commit>复制旧信息,然后打开当前提交再次修改并将信息粘贴到编辑器中:
终端git commit --amend这样可以保留当前的文件更改,并避免重置分支。
同事拉取后旧提交重新出现
拥有原始提交然后合并而不是变基的协作者会将两个版本都带回历史中。在将他们的分支指向重写后的远程状态之前,他们应该为本地提交创建备份分支,并暂存未提交和未跟踪的更改:
git branch backup-before-sync
git stash push -u警告以下重置会使当前分支匹配 origin/main。它会丢弃未暂存且未备份的更改,并从本地仅有的提交中移除当前分支引用。只有在确认备份分支存在且任何所需的工作树更改都已暂存后才能运行此命令。仅在创建这些备份后获取并重置分支:
终端git fetch origin
git reset --hard origin/mainbackup-before-sync 分支使本地仅有的提交保持可达。在删除它之前检查它,并在确认分支历史正确后使用 git stash pop 恢复暂存的更改。
常见问题解答
我能否在不修改提交信息的情况下修改提交?
可以。在暂存你想要添加的更改后,使用 git commit --amend --no-edit。Git 会使用新内容重写该提交,但保留原始提交信息。
--force 与 --force-with-lease 之间有什么区别?--force 无条件覆盖远程分支。--force-with-lease 会检查自上次拉取以来是否有人推送到了该分支,如果有则中止操作。在向共享仓库推送修改后的提交或变基后的提交时,始终优先使用 --force-with-lease。
我应修改(amend)还是还原(revert)已推送的提交?
修改会重写历史记录,并需要强制推送,这可能会影响协作者。如果提交已在共享分支上,通常更安全的选择是还原它,这会创建一个新提交来撤销更改,而不改变历史记录。
我可以在 GitHub 或 GitLab 上修改提交信息吗?
不能。GitHub 和 GitLab 都无法通过网络界面编辑现有提交信息。你必须在本地修改或重写提交信息并强制推送分支,这会更新托管站点上显示的信息。
如何完全撤销上一次提交?
使用 git reset 来移动分支指针。git reset --soft HEAD~1 会将更改保留在暂存区;git reset --hard HEAD~1 会完全丢弃这些更改。
我可以同时修改提交作者和信息吗?
可以。每个提交记录创建时配置的作者身份。要连同提交信息一起更新作者,请添加 --reset-author:git commit --amend --reset-author -m "新提交信息。"。