我有一个项目,我通过develop
分支分支工作,在feature
分支中做一些工作,将其合并回develop
。在此之后,我删除了feature
分支。
由于需要交叉合并等,我的提交历史非常难看。但是我在合并后仍然delete
有功能分支,但是我的git跟踪了拥有不同父母的提交。
如何将此树线性化为一行?那里只有一个分支,develop
。
编辑:这不是merge和rebase的重复,因为我想更新我的树后事实,现在只有一个分支。
答案 0 :(得分:1)
让我们考虑历史中第一个蓝色节点,其中丑陋的分支开始是起点。我们称之为哈希S
。
首先,让我们收集一个我们想要线性化的提交列表:
git log --oneline --reverse --full-history --simplify-merges S..HEAD > commits
现在,让我们扔掉所有历史记录并将分支重置回S
:
git reset --hard S
最后,让我们使用git rebase --interactive
将这些提交选入分支:
# Null rebase with no commits: git rebase -i HEAD
现在我们坐在一个文本编辑器中,缓冲区包含单词noop
:我们发起了一个空白的空白。删除noop
行,在其位置,将commits
文件读入编辑缓冲区。在每一行的前面,添加前缀p
以选择该提交。根据需要重新安排订单。然后保存并退出。交互式rebase脚本将很乐意和我们添加到缓冲区中的所有提交。
您现在必须处理交互式rebase工作流程,以解决因这些选择顺序而产生的任何冲突。
这可能是一步到位的,也许是git rebase -i S
。我不确定rebase如何处理错综复杂的历史。上述方法使其具体化;我们调整git log
选项以提取我们想要的确切提交列表,如果我们对commits
文件中的内容感到满意,我们(ab)使用交互式rebase来挑选它对我们来说。
您应该三次检查commits
是否包含图表中的内容。尘埃落定后,执行git diff <original-HEAD-SHA>
查看不同之处。理想情况下,应该没有任何区别,或者只是基于稍微不同地做一些合并解决方案的一些微不足道的差异(例如某些函数中的变量声明顺序等)。
答案 1 :(得分:0)
@Kaz建议以交互方式重新设置所有内容,但这会给合并带来巨大的麻烦,而且我找到了更好的方法。
首先这样做:
git filter-branch --parent-filter 'cut -f 2,3 -d " "'
完成后,执行git push -f