Skip to content

Git - 提交修改

有时你创建了一个 commit(提交),然后意识到在 commit message(提交信息)中犯了错误,或者忘记包含某个文件,或者想在最后一次 commit 中添加一个小的修改。Git 的 commit --amend 操作允许你修改你最近的 commit。

重要提示:修改(Amending)commit 会 重写 该 commit。它会创建一个新的 commit ID。如果你已经将原始 commit 推送(push)到了共享的 remote repository(远程仓库),通常应该避免修改它。如果你确实修改了已经推送的 commit,你需要使用 force-push(强制推送)来推送你的更改(git push --force-with-lease 比 git push --force 更安全),这可能会干扰那些基于原始 commit 进行工作的协作者。修改尚未共享的本地 commit 通常是安全的。

假设 Jerry 进行了一次 commit。他可以查看 commit 日志:

[jerry@dev-machine project]$ git log -1 --oneline
cbe1249 (HEAD -> main) Implemented my_strlen function

原始 commit 详情:

commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <jerry@example.com>
Date: Wed Sep 11 08:05:26 2013 +0530
Implemented my_strlen function

现在,Jerry 意识到他需要在 string_utils.c 中更新 my_strlen 的返回类型,并希望将此更改包含在 同一个 commit 中,或者可能只是想重写 commit message。

首先,他进行必要的代码修改。然后,他将它们 staging(暂存):

[jerry@dev-machine project]$ # ... Jerry modifies string_utils.c ...
[jerry@dev-machine project]$ git status -s
M string_utils.c
[jerry@dev-machine project]$ git add string_utils.c
[jerry@dev-machine project]$ git status -s
M string_utils.c

现在,Jerry 不是创建一个新的 commit,而是使用 git commit --amend。这将把当前 staging 的更改与上一个 commit 的内容合并。它还会打开他配置的文本编辑器,允许他更改 commit message。

[jerry@dev-machine project]$ git commit --amend

如果 Jerry 只想更改 commit message 而不添加新的文件更改,他可以在不 staging 新文件的情况下运行 git commit --amend。若要直接从命令行更改 message 并包含 staging 的更改,可以使用:

[jerry@dev-machine project]$ git commit --amend -m 'Changed return type of my_strlen to size_t and updated logic'
[main d1e19d3] Changed return type of my_strlen to size_t and updated logic
Date: Wed Sep 11 08:05:26 2013 +0530
1 file changed, 5 insertions(+), 2 deletions(-)

现在,如果 Jerry 查看日志,他会看到 amended commit 的 新 commit ID,旧的 commit cbe1249 不再是 main branch(分支)的 tip(顶端):

[jerry@dev-machine project]$ git log -1 --oneline
d1e19d3 (HEAD -> main) Changed return type of my_strlen to size_t and updated logic

新 commit 的完整日志:

commit d1e19d316224cddc437e3ed34ec3c931ad803958 (HEAD -> main)
Author: Jerry Mouse <jerry@example.com>
Date: Wed Sep 11 08:05:26 2013 +0530
Changed return type of my_strlen to size_t and updated logic

原始 commit cbe1249 现在是一个 orphaned commit(孤儿 commit)(除非有其他 branch 或 tag 指向它),如果它变得不可达,最终会被 Git 进行 garbage collection(垃圾回收)。