快速、小型、随意 git 仅针对一个或几个大块头进行变基:任何设施?
Quick, small, casual git rebase for only one or a few hunks: any facility?
我正在编辑我的源文件以在我的 dev
分支上生成一个新的提交。我的更改已保存在磁盘上但尚未暂存。
然后我注意到一个小错误是由以前的提交引入的,比如 HEAD~10
。一旦修复,结果是我的磁盘上只有一个(或几个)额外的 git diff hunk。
我不希望这些帅哥被记录在新的提交中,因为他们属于 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 发生冲突,我会收到警告)
Interactive rebase 已经有一个内置的方法来处理这个问题。让我们来演示一下。我们首先检查一些现有分支名称的提示提交:
git switch main
然后创建我们的功能或主题分支:
git switch -c topic
我们开始工作并进行提交,其中有一个小错误:
... edit ...
git add frotz.c
git commit
假设这是提交 a123456
(稍后我们将通过 git log
找到哈希 ID,或者我们将像您在示例中所做的那样使用 HEAD~10
;我只是想在这里放些具体的东西。
我们做了更多的提交:
... 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
使用 specially-formatted 提交消息。
现在我们有了修复提交,我们 运行:
git rebase -i --autosquash main
(因为 topic
是基于 main
;在这里使用你需要的任何东西)。带有所有 pick
命令的表单弹出,但是当我们仔细观察它时,我们发现其中一行没有说 pick
,而是说 fixup
:
pick a123456 commit subject line
fixup b789abc fixup! commit subject line
pick 9876543 another commit subject
... and so on ...
写出这组命令(或者不打扰,因为我们不需要改变它们)并退出编辑器会启动实际的 rebase,它...吸收修复提交 into 糟糕的 提交,所以它现在只是一个提交。
fixup
命令基本上告诉 Git:将此提交压缩到上一个提交中,同时完全删除此提交的日志消息。 使用 squash
而不是 fixup
告诉 Git: 将这个提交压缩到前一个,但停下来给我一个机会写一条新的日志消息,向我展示两个现有的日志消息. 这些实际上是相同的 除了 有机会编辑提交消息。
因为你没有提到要修复提交消息,所以我们在这里使用 --fixup
。要自动获取“挤压”命令,请使用 git commit --squash
。在这两种情况下,git commit
安排未来 git rebase --autosquash
看到一条消息,告诉 rebase 重新排列 pick 命令的顺序,并根据需要将第二个更改为 squash 或 fixup.
与往常一样,您也可以re-order and/or 手动修改说明。 (我通常这样做而不是使用 git commit --fixup
,因为我经常想做很多提交消息重写,并考虑要合并哪些提交以及将它们放入的顺序。)
我正在编辑我的源文件以在我的 dev
分支上生成一个新的提交。我的更改已保存在磁盘上但尚未暂存。
然后我注意到一个小错误是由以前的提交引入的,比如 HEAD~10
。一旦修复,结果是我的磁盘上只有一个(或几个)额外的 git diff hunk。
我不希望这些帅哥被记录在新的提交中,因为他们属于 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 发生冲突,我会收到警告)
Interactive rebase 已经有一个内置的方法来处理这个问题。让我们来演示一下。我们首先检查一些现有分支名称的提示提交:
git switch main
然后创建我们的功能或主题分支:
git switch -c topic
我们开始工作并进行提交,其中有一个小错误:
... edit ...
git add frotz.c
git commit
假设这是提交 a123456
(稍后我们将通过 git log
找到哈希 ID,或者我们将像您在示例中所做的那样使用 HEAD~10
;我只是想在这里放些具体的东西。
我们做了更多的提交:
... 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
使用 specially-formatted 提交消息。
现在我们有了修复提交,我们 运行:
git rebase -i --autosquash main
(因为 topic
是基于 main
;在这里使用你需要的任何东西)。带有所有 pick
命令的表单弹出,但是当我们仔细观察它时,我们发现其中一行没有说 pick
,而是说 fixup
:
pick a123456 commit subject line
fixup b789abc fixup! commit subject line
pick 9876543 another commit subject
... and so on ...
写出这组命令(或者不打扰,因为我们不需要改变它们)并退出编辑器会启动实际的 rebase,它...吸收修复提交 into 糟糕的 提交,所以它现在只是一个提交。
fixup
命令基本上告诉 Git:将此提交压缩到上一个提交中,同时完全删除此提交的日志消息。 使用 squash
而不是 fixup
告诉 Git: 将这个提交压缩到前一个,但停下来给我一个机会写一条新的日志消息,向我展示两个现有的日志消息. 这些实际上是相同的 除了 有机会编辑提交消息。
因为你没有提到要修复提交消息,所以我们在这里使用 --fixup
。要自动获取“挤压”命令,请使用 git commit --squash
。在这两种情况下,git commit
安排未来 git rebase --autosquash
看到一条消息,告诉 rebase 重新排列 pick 命令的顺序,并根据需要将第二个更改为 squash 或 fixup.
与往常一样,您也可以re-order and/or 手动修改说明。 (我通常这样做而不是使用 git commit --fixup
,因为我经常想做很多提交消息重写,并考虑要合并哪些提交以及将它们放入的顺序。)