将一个家长的提交移交给另一个家长

时间:2019-05-29 13:35:07

标签: git rebase git-rewrite-history

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

以下是当前历史记录的片段。我想将e5cb9b8提交重新建立到1a92e84的基础上,这样我就可以在历史记录图中获得一到两个深度级别(在视觉上,更改e5cb9b8的父级)。我已经尝试了

git rebase -p --onto 1a92e84 e5cb9b8 master

并选择从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

预期:

* | 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

我已经在StackOverflow上搜索了类似的问题,似乎没有人描述过如此深的修改。

解决方案

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

获得预期的历史记录图
git rebase -ir --onto 1a92e84 81761ff develop

并替换todo-list的followig片段

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

具有以下内容(更改了重置位置并删除了一个冗余的合并提交):

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

*) 实际上,要实现该状态还有更多工作要做,但是我不想使解决方案带有次要问题。第一个git rebase失败,并显示以下消息:

  

错误:拒绝更新名称为“ refs / rewrite / Implement-durability-loss”的引用。

     

提示:无法执行todo命令

     

提示:标签工具耐用性损失。

如您所见,提交消息的末尾有一个句点。解决了这一问题之后(使用reword命令进行了另一个重新设置),我得以继续前进。

此外,似乎git rebase --abort doesn't clear是在git rebase -r期间创建的裁判。通过rm -rf .git/refs/rewritten解决了该问题。另一件事,我有一个剩余的.git / sequencer文件夹,可以通过git revert --quit来删除。

2 个答案:

答案 0 :(得分:2)

您选择的基准库是错误的,应该是81761ff而不是e5cb9b8。我建议您进行交互式变基,并使用--rebase-merges而不是--preserve-merges。所以命令应该是:

git rebase -ir --onto 1a92e84 81761ff master

现在,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...

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

对于大多数用户和用例来说,这是相当高级的,并且真的是不需要的,因此请考虑man git-rebase Rebase Merges 部分(或{{3} })以获取更深入的信息。实际上,该示例与您的情况非常相似。

答案 1 :(得分:0)

如果您使用git rebase -ir,请使用Git 2.25(2020年第一季度)。

todo生成的git rebase --rebase-merges列表中使用的标签用作refname的一部分;标签上的逻辑已被严格化,以避免名称不能这样使用。

请参见commit cd55222Matthew Rogers (soniqua)(2019年11月17日)。
请参见commit 867bc1dJohannes Schindelin (dscho)(2019年11月17日)。
(由Junio C Hamano -- gitster --commit 917d0d6中合并,2019年12月5日)

  

rebase -r:让label生成更安全的标签

     

签名人:马修·罗杰斯
  签名人:Johannes Schindelin

     

交互式基础中的label todo命令在refs/rewritten/名称空间中创建临时引用。这些引用存储为松散引用,即存储为.git/refs/rewritten/中的文件,因此,除了可接受的引用格式外,它们还必须符合当前文件系统上文件名的限制。

     

尤其是在NTFS / FAT上,这会带来问题。文件名不允许使用冒号,双引号和竖线字符。

     

为此,我们不仅要用破折号来代替空格字符,还要用所有非字母数字来代替。

     

但是,我们免除了非ASCII UTF-8字符,因为应该很可能在引用/文件名中反映诸如↯↯↯之类的分支名称。


并且:

在Git 2.25(2020年第1季度)中,避免由“ git rebase --rebase-merges”生成的重复标​​签名称的逻辑忘记了机器本身使用“ onto”作为标签名称,必须避免使用自动生成的标签,该标签已得到纠正。

请参见commit e02058aDoan Tran Cong Danh (congdanhqx-zz)(2019年11月18日)。
(由Junio C Hamano -- gitster --commit 995b1b1中合并,2019年12月5日)

  

sequencer:处理“ onto”消息的重新合并

     

签名人:Doan Tran Cong Danh
   Acked-by:约翰内斯·辛德尔林

     

为了正常工作,git rebase --rebase-merges需要制作带有唯一标签的初始待办事项列表。

     

通过使用哈希图并在发现重复项时附加唯一编号来处理这些唯一标签。

     

但是,我们忘记了,除了那些用于侧枝的标签之外,我们还为我们的新基地提供了一个特殊标签onto

     

在特殊情况下,那些名为“ onto”的侧分支的标签中的任何一个,git都会遇到麻烦。

     

更正它。