如何自动压缩git存储库历史记录,没有冲突,以便缩小它?

时间:2014-10-24 19:57:01

标签: git squash

我的存储库已经变得太大而无法使用。基本上我的存储库超过2GB,克隆时间太长。我现在想缩小它,但仍然能够回到一些特定的旧版本...... 萎缩将涉及重写历史,所以我很好。有克隆的人将不得不在新的repo clone中的新分支上重新定位/ cherrypick / copyfiles。

  • 我在这个存储库中有二进制文件,但我需要它们(将其视为软件运行的必备资源)。所以我不能真正使用filter-branch或BFG删除一些大的二进制文件,因为在恢复到过去的提交时我可能需要它们。
  • 我不关心以前的旧/已经合并的分支(例如:功能分支),但我关心一些特定的提交(过去发布分支的示例头)
  • 由于我将修改(〜很多〜)非常旧的提交,我现在不知道如何解决正确的合并冲突(可能发生在基本的rebase / cherrypick),所以我正在寻找一个不会产生任何问题的解决方案冲突,或只产生可以自动解决的冲突。
  • 我想保留所有当前的分支,因此在克隆上进行工作的人可以对它们进行rebase / copychange。
  • 我希望在我的新提交之间有相关的历史记录来匹配旧回购的历史记录(好像提交被压扁了)。当前分支机构的历史将从这些旧的压缩提交之一开始。

我认为这是一个不必要的旧存储库历史记录。到目前为止,我提出的一个可能的过程(我错过了一些步骤,我仍然不确定这会做我认为的):

  • 克隆现有仓库的镜像。
  • 从我想要保留的旧提交中创建孤立分支。这将创建无父类压缩提交及其中所需的所有文件。
  • 以某种方式链接它们以重新创建旧的repo history =>怎么样 ? merge / rebase / reset + commit orphans?
  • Cherrypick每个当前分支的提交列表(使用间隔),并将它们应用于压缩其第一个发散提交的父级的最新提交=>如何自动查找应用樱桃挑选提交间隔的提交?那会没有冲突吗?
  • 将标记移动到新树。删除以前的树。 git垃圾收集。

这是可行的/可行的,没有任何冲突吗? 这可以在任何情况下工作(git commit tree可能相当复杂)? 有没有更好的安全和自动压缩历史的解决方案?

在我看来,这种类型的维护任务会在长期运行的项目中发生,所以我假设其他大型项目已经使用了某种类型的解决方案。但我想可能有一个我不知道的git init(或其他命令)的选项,从旧的repo为这个用例创建一个新的repo?

更新:我在这里找到了解决方案的开头:https://wincent.com/wiki/Editing,_amending,_or_squashing_the_root_commit_in_a_Git_repository 但我想以一种全自动的方式(即没有冲突)多次进入我的历史......

3 个答案:

答案 0 :(得分:1)

您只能克隆回购的一部分:

git clone --depth depth 

这被称为浅层克隆。

前一段时间是post on the Atlassian blog,提供了处理大型回购的其他策略。

答案 1 :(得分:1)

好的,经过几天的试用和错误,这是我认为最好的解决方案:

1)从您想要用作新root的提交中,执行checkout --orphan创建孤立分支,并为此版本提交已更改的文件。

2)对于您要保留的每个提交C,checkout提交C,reset到先前的新提交B',提交进行C'新提交,B'作为父提交。 (感谢forvaidya获取链接)

3)您现在需要将现有分支重新链接到您保留的最后一次提交。 在旧历史中查找提交。从那里,列出所有具有它(或其任何一个父)的提交作为直接父。然后,您可以使用新的git replace --graft将旧的父级替换为新的提交。

为这个提出一个万无一失的脚本是非常有用的......如果我这样做,我会把它发布在这里。

警告:步骤3)仅在您使用git 2.X时有效。 1.X git客户端不会在提交图中看到更改。

答案 2 :(得分:0)

Git浅层克隆是一个答案,但是克隆很浅,你无法推送。

至于壁球有关壁球仅适用于未发表的历史记录,此链接可能有用http://www.awanitech.com/git-squash.html

推送后完成的任何压缩都需要在不同的分支上进行,因为它不是FF推送。这种壁球不会对存储库大小产生影响。

如果你准备做强制推(历史重写);那么你可以做filter-branch并减小尺寸。

如果你的坏版本是完全不同的分支;你可以创建一个git包并将其作为简化的存储库。