我通常会提交一份提交列表以供审核。如果我有:
HEAD
Commit3
Commit2
Commit1
我知道我可以使用git commit --amend
修改头部提交,但是如果它不是HEAD
提交,我如何修改Commit1
?
例如,如果要修改回提交bbc643cd
,则可以使用 git rebase 运行
$ git rebase --interactive 'bbc643cd^'
在默认编辑器中,修改要edit
其提交的行中的pick
以进行edit
。进行更改,然后使用之前的相同消息提交它们:
$ git commit --all --amend --no-edit
修改提交,然后修改
$ git rebase --continue
返回上一个头部提交。
警告 :请注意,这将更改该提交的 SHA-1 以及所有子项 - 换句话说,这将从该点向前重写历史记录。如果使用命令git push --force
推送,则可以中断 repos 执行此操作
git rebase -i @~9 # Show the last 9 commits in a text editor
找到您想要的提交,将pick
更改为e
( edit
),然后保存并关闭该文件。 Git 将回退到该提交,允许您:
git commit --amend
进行更改,或者git reset @~
来丢弃最后一次提交,但不是对文件的更改(即带你到你编辑文件时所处的位置,但还没有提交)。 后者对于执行更复杂的操作(如拆分为多个提交)非常有用。
然后,运行git rebase --continue
,Git 将在修改后的提交之上重放后续更改。系统可能会要求您修复某些合并冲突。
注意: @
是HEAD
简写, ~
是指定提交之前的提交。
阅读有关在 Git 文档中重写历史记录的更多信息。
ProTip™:不要害怕尝试重写历史记录的 “危险” 命令 * - Git 默认情况下不会删除你的提交 90 天; 你可以在 reflog 中找到它们:
$ git reset @~3 # go back 3 commits
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~3
2c52489 HEAD@{1}: commit: more changes
4a5246d HEAD@{2}: commit: make important changes
e8571e4 HEAD@{3}: commit: make some changes
... earlier commits ...
$ git reset 2c52489
... and you're back where you started
* 注意像--hard
和--force
这样的选项 - 他们可以丢弃数据。
* 此外,不要在您正在协作的任何分支上重写历史记录。
在许多系统上, git rebase -i
默认会打开 Vim。 Vim 不像大多数现代文本编辑器那样工作,所以看看如何使用 Vim 进行 rebase 。如果您更愿意使用其他编辑器,请使用git config --global core.editor your-favorite-text-editor
更改。
当我需要--autosquash
历史上更深层次的提交时,我经常使用带有--autosquash
交互式rebase 。它实质上加快了 ZelluX 的答案所说明的过程,当您需要编辑多个提交时,这一过程尤其方便。
从文档:
--autosquash
当提交日志消息以 “squash!...”(或 “fixup!...”)开头,并且有一个提交标题以相同的... 开头时,自动修改 rebase -i 的待办事项列表以便提交标记为压缩是在提交修改后立即进行的
假设您的历史记录如下所示:
$ git log --graph --oneline
* b42d293 Commit3
* e8adec4 Commit2
* faaf19f Commit1
并且您有要修改为 Commit2 的更改,然后使用提交更改
$ git commit -m "fixup! Commit2"
或者你可以使用 commit-sha 而不是 commit 消息,所以"fixup! e8adec4
甚至只是提交消息的前缀。
然后在提交之前启动交互式 rebase
$ git rebase e8adec4^ -i --autosquash
您的编辑器将打开已经正确订购的提交
pick e8adec4 Commit2
fixup 54e1a99 fixup! Commit2
pick b42d293 Commit3
你需要做的就是保存并退出