我们有一个历史悠久的git项目。
具体来说,在项目早期,项目中存在大量二进制资源文件,这些文件现已被删除,因为它们实际上是外部资源。
但是,由于先前已提交这些文件,我们的存储库大小> 200MB(总结账时间约为20MB)。
我们要做的是“折叠”历史记录,以便存储库看起来是从以后的版本创建的。例如
1-----2-----3-----4-----+---+---+
\ /
+-----+---+---+
因此,我们希望在某一点之前丢失项目历史记录。此时只有一个分支,因此尝试处理多个起点等没有复杂性。但是我们不想丢失所有历史记录并使用当前版本启动新的存储库。
这是可能的,还是我们注定要永远拥有一个膨胀的存储库?
答案 0 :(得分:87)
您可以移除二进制膨胀并保留其余历史记录。 Git允许您重新排序和“压缩”先前的提交,因此您只需要组合添加和删除大二进制文件的提交。如果添加都在一次提交中完成,而删除则在另一次提交中完成,这将比处理每个文件容易得多。
$ git log --stat # list all commits and commit messages
在此处搜索添加和删除二进制文件的提交,并记下其SHA1,例如2bcdef
和3cdef3
。
然后要编辑repo的历史记录,请使用rebase -i
命令及其交互选项,从添加二进制文件的提交的父级开始。它将启动您的$ EDITOR,您将看到以2bcdef
开头的提交列表:
$ git rebase -i 2bcdef^ # generate a pick list of all commits starting with 2bcdef
# Rebasing zzzzzz onto yyyyyyy
#
# Commands:
# pick = use commit
# edit = use commit, but stop for amending
# squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
pick 2bcdef Add binary files and other edits
pick xxxxxx Another change
.
.
pick 3cdef3 Remove binary files; link to them as external resources
.
.
插入squash 3cdef3
作为第二行,并从列表中删除显示pick 3cdef3
的行。您现在有一个交互式rebase
的操作列表,它将把添加和删除二进制文件的提交组合到一个提交中,其中diff只是这些提交中的任何其他更改。然后,当您告诉它完成时,它将按顺序重新应用所有后续提交:
$ git rebase --continue
这将需要一两分钟 你现在有一个不再拥有二进制文件的回购。但是他们仍然会占用空间,因为默认情况下,Git会在垃圾收集之前保持30天左右的变化,以便您可以改变主意。 如果你想现在删除它们:
$ git reflog expire --expire=1.minute refs/heads/master
#all deletions up to 1 minute ago available to be garbage-collected
$ git fsck --unreachable # lists all the blobs(files) that will be garbage-collected
$ git prune
$ git gc
现在你已经删除了膨胀,但保留了历史的其余部分。
答案 1 :(得分:26)
您可以使用git filter-branch
和grafts将提交编号4作为分支的新根提交。只需创建文件.git/info/grafts
,其中只有一行包含提交号为4的SHA1。
如果您现在执行git log
或gitk
,您将看到这些命令将显示提交编号4作为分支的根目录。但是在您的存储库中实际上没有任何改变。您可以删除.git/info/grafts
,git log
或gitk
的输出将与以前一样。要实际将提交编号4设为新根,您必须运行git filter-branch
,不带参数。
答案 2 :(得分:20)
感谢JesperE的帖子,我调查了git-filter-branch
- 这可能实际上就是你想要的。看起来你可以保留你之前的提交,除非你的大文件被删除后它们会被修改。来自git-filter-branch man page:
假设您要从所有提交中删除文件(包含机密信息或侵犯版权):
git filter-branch --tree-filter'rm filename'HEAD
请务必阅读该手册页...显然,您希望在存储库的备用克隆上执行此操作,以确保其按预期工作。
答案 3 :(得分:5)
git-fast-export
您要找的是什么?
NAME
git-fast-export - Git data exporter
SYNOPSIS
git-fast-export [options] | git-fast-import
DESCRIPTION
This program dumps the given revisions in a form suitable to be piped into git-fast-
import(1).
You can use it as a human readable bundle replacement (see git-bundle(1)), or as a kind
of an interactive git-filter-branch(1).