修复具有重复提交的git历史记录
短版本:修复具有重复提交的git历史记录,git,Git,短版本: 如何从左边的图转到右边的图。另外,我是否需要手动清除重复提交(root2,a',b'),或者GC将在将来的某个时候删除它们? 长版本: 由于CVS到git端口的错误,当我从CVS导入分支_1时,在git中已经创建了master,我在同一个repo中得到了两个备用历史记录。可以看出,分支_1的提交是唯一的,但也有其他提交是重复的。解决这个问题最简单的方法是什么 我有一些想法,但不知道如何执行。一种方法是完全删除分支1并重新开始,但我不知道如何让git认识到root1和root2是相同的
如何从左边的图转到右边的图。另外,我是否需要手动清除重复提交(root2,a',b'),或者GC将在将来的某个时候删除它们? 长版本:
由于CVS到git端口的错误,当我从CVS导入分支_1时,在git中已经创建了master,我在同一个repo中得到了两个备用历史记录。可以看出,分支_1的提交是唯一的,但也有其他提交是重复的。解决这个问题最简单的方法是什么 我有一些想法,但不知道如何执行。一种方法是完全删除分支1并重新开始,但我不知道如何让git认识到
root1
和root2
是相同的,以便所有补丁都应用在同一行上。另一个想法是将f,g,h重设为b,并以某种方式删除root2,a'和b'。但我认为,由于没有共同的祖先,正常的重基将不起作用
实际上,分支的重复提交和唯一提交有数百个,因此一些非常手动的操作并不好您可以先尝试一个非破坏性的选项,即使用: 在图表中,用commit
f
和b
的sha1替换这些
这一变更将是非永久性的,但应能够通过以下方式进行审查:
git log --graph --all --decorate
如果一切正常,您可以运行以使这些更改永久化
请注意,除非您执行一个
git过滤器分支
并按下按钮,否则其他人不会看到这些更改。这可以被认为是一个“特性”,因为它不会强迫其他任何人对他们的工作进行混乱的重新基调。这基本上只是添加了一些额外的信息,告诉像git log这样的工具,这样,当他们看到commit“f”时,他们应该假装它有一个“b”的父对象,而不实际更新commit对象来反映这一点。更改提交对象的父对象将更改其SHA1,这意味着需要更新其子提交以指向新的SHA1,然后再更新其子对象等。请注意,您请求的重基将重写分支1上所有提交的提交哈希。我正在使用b
和b'
来指示在您美丽的图形中提交的提交哈希
git checkout branch_1
git rebase --onto b b'
这与手册页面中的以下形式的git-rebase
相匹配:
git rebase --onto <newbase> <upstream>
git-rebase-on
根据手册,将发生以下情况
中的所有更改都将保存到临时区域--on
选项,则当前分支将重置为
,或
在IIUC中,重定基址的工作方式是重放当前分支中自两个分支之间的最后一个公共祖先以来的提交。就我而言,没有共同的祖先。所以要么失败,要么把root2作为b的子代。这两种情况都是错误的。我遗漏了什么吗?@Hilikus,看看
mangit-rebase
和grep中的--to
选项。我需要操纵回购来删除重复提交,还是说它们悬空的事实意味着它们将在某个点上被终止?我不太清楚提交是否会在回购协议上永久存在,或者是否需要能够访问这些提交才能永久存在,否则提交将始终被垃圾收集eventually@dietrichepp虽然我大体上同意你的看法,但op表示他正在试图消除重复提交。我建议你不要使用git rebase,因为它保留两个分支的内容(树)git rebase
保留更改(差异)。@DietrichEpp您的意思是我将以左图结束,但从b
到f
有一条额外的边?如果这就是你所说的“保留树木”的意思,我不希望因为这两棵树都是重复的。不,你基本上会得到右边的图表,但它不会重写你的任何历史。@Hilikus:你会得到右边的图片,除了f,g,h之外,我会给它们贴上f',g',h',的标签,因为它们将有不同的提交哈希。你仍然重写历史,你只是不改变任何树的内容。重写历史记录后,可以删除grafts
文件。
git rebase --onto <newbase> <upstream>