Appearance
修改提交
提交后发现需要修改——这是很常见的情况。Git 提供了几种方式来修改已有的提交。
git commit --amend:修改最近提交
--amend 是修改最近一次提交的标准方式,它会用新的提交替换最后一次提交:
只修改提交信息
bash
git commit --amend
# 打开编辑器,修改提交信息
# 或者直接在命令行指定新信息
git commit --amend -m "fix: 修正提交信息中的拼写错误"追加遗漏的文件到上一次提交
bash
# 发现提交时忘了某个文件
git add forgotten-file.js
# 追加到上一次提交,不修改提交信息
git commit --amend --no-edit
# 追加到上一次提交,同时修改提交信息
git add forgotten-file.js
git commit --amend -m "feat: 添加用户登录功能(包含遗漏的配置文件)"amend 的本质
--amend 实际上是创建了一个新的提交,替换掉原来的提交(SHA-1 会改变):
amend 前:
... ← A ← B (HEAD)
amend 后:
... ← A ← B' (HEAD)(B 的 SHA-1 不同)
B 仍然存在于 reflog 中,但不再被任何引用指向修改更早的提交(rebase -i + edit)
要修改非最近的提交,使用交互式 rebase:
bash
# 修改最近 3 个提交中的某一个
git rebase -i HEAD~3
# 编辑器显示:
# pick abc123 feat: 功能A ← 想修改这个
# pick def456 feat: 功能B
# pick ghi789 fix: 修复C
# 将要修改的提交的 "pick" 改为 "edit"(或 "e"):
# edit abc123 feat: 功能A
# pick def456 feat: 功能B
# pick ghi789 fix: 修复C保存退出后,Git 会暂停在 abc123 提交处:
bash
# 此时可以修改文件
vim src/feature-a.js
# 也可以修改提交信息
git commit --amend -m "feat: 修正后的功能A描述"
# 或者只修改文件,不修改信息
git add .
git commit --amend --no-edit
# 继续 rebase
git rebase --continue注意事项:已 push 的提交不要 amend
这是最重要的规则:
已推送到远程且被他人拉取的提交,不要修改!
原因:amend 会改变 SHA-1
其他人的本地仓库有旧的 SHA-1 对应的提交
你 amend 后推送(需要 force push)
他们 pull 时会遇到历史冲突,需要复杂的修复什么情况下可以修改已推送的提交:
- 个人私有分支:只有你自己在用的功能分支
- 所有协作者都知情并同意:团队一致同意重写历史
- PR 分支:创建 PR 后,根据 review 意见修改提交历史
需要 force push 时用 --force-with-lease:
bash
# 修改了历史后,需要强制推送
git push --force-with-lease修改已推送提交的安全方案
如果真的需要修改已推送的提交(如清除敏感信息),正确的流程是:
bash
# 1. 使用 rebase -i 修改
git rebase -i HEAD~3
# 2. 通知所有协作者
# "我将 force push feature/xxx,请在我完成后重新 fetch"
# 3. Force push
git push --force-with-lease origin feature/xxx
# 4. 协作者需要重置本地分支
git fetch origin
git reset --hard origin/feature/xxx修改提交信息的最佳实践
bash
# 修改最近一次提交信息
git commit --amend -m "fix(auth): 修复令牌过期后未重定向问题"
# 修改并添加详细说明
git commit --amend
# 在编辑器中:
# fix(auth): 修复令牌过期后未重定向问题
#
# 令牌过期时,之前的代码只是返回 401,
# 没有清除本地存储的过期令牌,导致循环请求。
#
# 现在改为:检测到 401 时,清除令牌并重定向到登录页。
#
# Closes #234总结
| 操作 | 命令 | 适用情况 |
|---|---|---|
| 修改最近提交信息 | git commit --amend -m "新信息" | 尚未推送 |
| 追加文件到最近提交 | git add file && git commit --amend --no-edit | 尚未推送 |
| 修改更早的提交 | git rebase -i HEAD~n → edit | 尚未推送 |
| 已推送的修改 | 慎重!需通知所有协作者 | 个人分支 |
黄金法则:未推送的提交随意修改,已推送的提交谨慎修改,已被他人拉取的提交不要修改。