git - 快速、小型、随意的 git rebase,仅适用于一个或几个帅哥 : any facility?

标签 git rebase git-stash git-amend git-stage

我正在编辑源文件,以在我的 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/

相关文章:

git - 当不进行 cherry-pick 时,之前的 cherry-pick 现在为空

git - 如何在 1.8.3 中 Git stash pop specific stash?

git - 如何让 Git 默认使用 "theirs" merge 策略?

git - 在没有克隆叉的情况下检查 repo 的分支分支

git rebase 导致 origin/master 和 master 出现分歧

git - 一次用子分支重新设置分支

git - 如何从 git merge --log 获取完整消息

git - 如何在不提交的情况下关闭 GitHub 问题?

git - git checkout HEAD -- filename 和 git checkout -- filename 的区别

git stash clear,除了特定的存储