我正在编辑源文件,以在我的 dev
分支上生成新的提交。我的更改已保存在磁盘上,但尚未暂存。
然后我注意到以前的提交引入了一个小错误,例如 HEAD~10
。修复后,结果只是我的磁盘上有一个(或几个)额外的 git diff hunk。
我不希望这些 block 被记录在新的提交中,因为它们属于 HEAD~10
。所以我需要重新调整基础。这是我的工作流程,但我对此不满意:
$ git stash # save my current work + the small fix
$ git rebase --interactive HEAD~11
# set first commit appearing in todo list to `edit` action
$ git stash pop # re-introduce my changes here (**may conflict**)
$ git add --patch fixed_files # or similar, to only stage relevant fix hunk(s)
$ git commit --amend # fix old commit
$ git stash # save my current work again
$ git rebase --continue # get back to my current commit (will likely *not* conflict)
$ git stash pop # back here with HEAD~10 fixed
令我不满意的是,这个过程很复杂,而且第一行git stash pop
可能会引入无意义的冲突,尽管我确信执行过程中不会发生冲突git rebase --continue
行的一部分。
还有更好的办法吗?假设我在 HEAD
中只有几个上演的帅哥,我可以轻松地在我的分支中早期引入它们并使用一些神奇的东西:
git amend-old-commit-then-rebase HEAD~10
还保留我未暂存的更改吗? (当然,如果固有的 rebase 确实发生冲突,我会被警告)
最佳答案
交互式 rebase 已经有一个内置的方法来处理这个问题。我们来演示一下。我们首先检查一些现有分支名称的提示提交:
git switch main
然后创建我们的功能或主题分支:
git switch -c topic
我们开始工作并进行一个有小错误的提交:
... edit ...
git add frotz.c
git commit
假设这是提交 a123456
(稍后我们将通过 git log
找到哈希 ID,或者我们将使用 HEAD~10
code> 就像你在示例中所做的那样;我只是想在这里放一些具体的东西)。
我们做出更多 promise :
... edit and commit repeatedly ...
然后发现错误。我们暂缓修复错误,进行我们需要的提交:
git commit
然后我们修复错误,git add
,并使用git commit --fixup
:
... edit frotz.c to fix the mistake ...
git add frotz.c
git commit --fixup a123456 # or git commit --fixup HEAD~10
--fixup
选项指示 git commit
使用特殊格式的提交消息。
现在我们已经提交了修复,我们运行:
git rebase -i --autosquash main
(因为 topic
是基于 main
的;在这里使用您需要的任何内容)。 pop 包含所有 pick
命令的表单,但是当我们仔细观察时,我们发现其中一行没有说 pick
,而是说 修复
:
pick a123456 commit subject line
fixup b789abc fixup! commit subject line
pick 9876543 another commit subject
... and so on ...
写出这组命令(或者不打扰,因为我们不需要更改它们)并退出编辑器会启动实际的 rebase ,这...吸收修复提交到 坏提交,所以现在只是一次提交。
fixup
命令基本上告诉 Git:将此提交压缩到前一个提交中,同时完全删除此提交的日志消息。 使用 squash
代替fixup
告诉 Git:将此提交压缩到前一个提交中,但停下来并给我一个机会编写新的日志消息,向我显示两条现有的日志消息。实际上是相同的,除了有编辑提交消息的机会。
由于您没有提到要修复提交消息,因此我们在这里使用了 --fixup
。要自动获取“squash”命令,请使用 git commit --squash 。在这两种情况下, git commit 都会安排将来的 git rebase --autosquash 看到一条消息,告诉 rebase 重新排列 pick 命令的顺序,并更改第二个一个适当的压缩或修复。
与往常一样,您也可以手动重新排序和/或修改说明。 (无论如何,我通常会这样做,而不是使用 git commit --fixup ,因为我经常想要进行大量提交消息改写,并考虑要 merge 哪些提交以及将它们放入什么顺序。 )
关于git - 快速、小型、随意的 git rebase,仅适用于一个或几个帅哥 : any facility?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71937661/