使用重复提交修复git历史记录

时间:2015-04-27 20:05:22

标签: git

简短版本:
如何从左图转到右图。另外,我是否需要手动清除重复提交(root2,a',b'),否则GC将在未来的某个时间点修剪它们? before-after

长版:
由于git端口的CVS错误,当我在git中创建master时,我从CVS导入branch_1时,在同一个repo中最终得到了两个备用历史记录。可以看出,branch_1的提交是唯一的,但还有其他的是重复的。解决这个问题的最简单方法是什么?

我有一些想法,但不知道如何执行它们。一个是完全删除branch_1并重新开始,但我不知道如何让git识别root1root2是相同的,以便所有补丁都应用于同一行。另一个想法是将 f,g,h 重新绑定到 b 并以某种方式删除 root2,' b'。但我认为,由于没有共同的祖先,正常的基础不起作用

实际上,分支的重复提交和唯一提交是数百个,所以非常手动的东西不好

2 个答案:

答案 0 :(得分:2)

您可以先尝试的一个非破坏性选项是使用Graft Point

# .git/info/grafts
0000000f 0000000b

将替换为图表中提交fb的SHA1。

此更改将是非永久性的,但应该可以通过以下方式进行审核:

git log --graph --all --decorate

如果一切看起来都不错,您可以运行git filter-branch来永久保留这些更改。

请注意,在您执行git filter-branch并推送之前,其他人都不会看到这些更改。这可以被认为是一个特色",因为它不会迫使其他人不得不对他们的工作进行凌乱的改变。这基本上只是增加了一些额外的信息,告诉像git-log这样的工具,当他们看到提交" f"时,他们应该假装它的父母是" b",没有实际上更新提交对象以反映它。更改提交对象的父级会更改其SHA1,这意味着需要更新其子提交以指向新的SHA1,然后指向其子级等。

答案 1 :(得分:1)

请注意,您要求的rebase将重写branch_1所有提交的提交哈希值。我使用bb'来表示你美丽人物中提交的哈希值。

git checkout branch_1
git rebase --onto b b'

这与手册页中的以下git rebase形式匹配:

git rebase --onto <newbase> <upstream>

根据手册,将会发生以下情况。

  1. 当前分支中但不在<upstream>中的提交所做的所有更改都会保存到临时区域。
  2. 如果提供了<upstream>选项,则当前分支将重置为<newbase>--onto
  3. 之前保存到临时区域的提交将按顺序逐个重新应用于当前分支。