将一个父级的提交重新绑定到另一个父级

Kam*_*nek 6 git rebase git-rewrite-history

我有一个正在处理的现有存储库,但最近我学到了很多关于良好实践和 git 本身的知识。我想根据自己的喜好改变我的历史,尤其是一些早期的提交。

以下是当前历史的片段。我想将 e5cb9b8 提交重新绑定到 1a92e84 上,这样我就可以在历史图中只有一个/两个级别的深度(从视觉上看,更改 e5cb9b8 的父级)。我试过变基

git rebase -p --onto 1a92e84 e5cb9b8 master
Run Code Online (Sandbox Code Playgroud)

并挑选到从 9ecbe00 创建的新分支。Cherrypicking 让我获得了平坦的历史,rebase 失败并显示以下消息

错误:提交 ca230d8c048d22de6f219da8a22e70a773827c38 是一个合并,但没有给出 -m 选项。

致命:樱桃挑选失败

无法选择 ca230d8c048d22de6f219da8a22e70a773827c38

* | 45a0a21 - (7 weeks ago) #17 Updates README.md - Kamil Pacanek
|/
*   ca230d8 - (8 weeks ago) Merge pull request #2 from KamilPacanek/feat/rmb-support-removing-parts - Kamil Pacanek
|\
| * e5cb9b8 - (8 weeks ago) Adds support for removing parts on ReactorCells - KamilPacanek
* |   1a92e84 - (8 weeks ago) Merge pull request #1 from KamilPacanek/enable-gh-pages - Kamil Pacanek
|\ \
| |/
| * 81761ff - (8 weeks ago) Adds GH Pages support - KamilPacanek
|/
* 9ecbe00 - (8 weeks ago) Initial commit - KamilPacanek
Run Code Online (Sandbox Code Playgroud)

预期的:

* | 45a0a21' - (7 weeks ago) #17 Updates README.md - Kamil Pacanek
|/
*   ca230d8' - (8 weeks ago) Merge pull request #2 from KamilPacanek/feat/rmb-support-removing-parts - Kamil Pacanek
|\
| * e5cb9b8' - (8 weeks ago) Adds support for removing parts on ReactorCells - KamilPacanek
|/
*    1a92e84 - (8 weeks ago) Merge pull request #1 from KamilPacanek/enable-gh-pages - Kamil Pacanek
|\ 
| |
| * 81761ff - (8 weeks ago) Adds GH Pages support - KamilPacanek
|/
* 9ecbe00 - (8 weeks ago) Initial commit - KamilPacanek
Run Code Online (Sandbox Code Playgroud)

我在 StackOverflow 上搜索过类似的问题,似乎没有人在历史上如此深入地描述过这种修改。

解决方案

好的,对于未来的读者和我自己,我正在写下我的问题的解决方案。@alfunx答案是解决它的关键 - 我已经在其他主题解释中找到了git rebasegit rebase --onto并开始在我的存储库上进行实验。通过反复试验,我设法*通过执行来实现预期的历史图

git rebase -ir --onto 1a92e84 81761ff develop
Run Code Online (Sandbox Code Playgroud)

并替换待办事项列表的后续片段

label onto

# Branch KamilPacanek/feat/rmb-support-removing-parts
reset onto
pick e5cb9b8 Adds support for removing parts on ReactorCells
label KamilPacanek/feat/rmb-support-removing-parts

# Branch enh/add-uranium-cells
reset 9ecbe00 # Initial commit
merge -C 1a92e84 onto # Merge pull request #1 from KamilPacanek/enable-gh-pages
merge -C ca230d8 KamilPacanek/feat/rmb-support-removing-parts # Merge pull request #2 from KamilPacanek/feat/rmb-support-removing-parts
label branch-point
Run Code Online (Sandbox Code Playgroud)

使用以下(更改重置位置并删除一个,冗余,合并提交):

label onto

# Branch KamilPacanek/feat/rmb-support-removing-parts
reset onto
pick e5cb9b8 Adds support for removing parts on ReactorCells
label KamilPacanek/feat/rmb-support-removing-parts

# Branch enh/add-uranium-cells
reset onto
merge -C ca230d8 KamilPacanek/feat/rmb-support-removing-parts # Merge pull request #2 from KamilPacanek/feat/rmb-support-removing-parts
label branch-point
Run Code Online (Sandbox Code Playgroud)

*) 实际上,要达到这种状态还有很多工作要做,但我不想用次要问题混淆解决方案。第一次git rebase失败并显示该消息:

错误:拒绝使用错误名称“refs/rewritten/Implement-durability-loss”更新 ref。

提示:无法执行 todo 命令

提示:标签Implement-durability-loss。

如您所见,我在提交消息的末尾有一个句点。在我解决了这个问题(使用另一个带有reword命令的变基)之后,我能够继续前进。

此外,似乎git rebase --abort 没有清除git rebase -r..期间创建的引用,所以我在历史上一团糟。通过rm -rf .git/refs/rewritten. 另一件事,我有一个剩余的 .git/sequencer 文件夹,可以通过 .git/sequencer 文件夹移除git revert --quit

alf*_*unx 6

你选择了底垫的基础是错误的,应该81761ff不是e5cb9b8。我建议你做一个交互式 rebase 并使用--rebase-merges而不是--preserve-merges. 所以命令应该是:

git rebase -ir --onto 1a92e84 81761ff master
Run Code Online (Sandbox Code Playgroud)

现在,Git 可能会产生一个额外的合并提交。为了避免这种情况并产生您想要的结果,您应该将待办事项列表调整为:

label onto
pick e5cb9b8 Adds support for removing parts on ReactorCells
label new
reset onto
merge -C ca230d8 new
pick 45a0a21 #17 Updates README.md
# Remaining commits...
Run Code Online (Sandbox Code Playgroud)

在 todo-list 中,label可用于标记当前提交(HEAD),reset并可用于设置HEAD某些提交/标签。merge显然用于产生合并提交,-C使合并使用与原始合并提交相同的提交消息。

这是非常先进的,对于大多数用户和用例来说确实不需要,因此请考虑Rebase Mergesman git-rebase部分(或此处的在线版本)以获取更深入的信息。那里的示例实际上与您的情况非常相似。

  • 谢谢@alfunx!这非常有帮助,因为我能够实现我想要的。我已经用解决方案更新了问题。 (2认同)