git删除文件的最旧版本

时间:2009-05-30 21:03:06

标签: git

我有一个33 MB的大文件,我想永久删除该文件的最旧版本,所以我只保留最新的X版本。怎么做?

我的裸存储库因此而变得庞大。

我尝试了以下内容..但它完全删除了文件

git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_manual.txt' HEAD

要识别我的存储库中的大文件,我使用git-large-blob by Aristotle Pagaltzis

3 个答案:

答案 0 :(得分:16)

我认为您使用您尝试的git filter-branch命令走在正确的轨道上。问题是你没有告诉它将文件保存在任何提交中,因此它将从所有提交中删除。现在,我认为没有办法直接告诉git-filter-branch跳过任何提交。但是,由于命令是在shell上下文中运行的,因此使用shell删除除最后X个修订版之外的所有修改都不应该太困难。像这样:

KEEP=10 I=0 NUM_COMMITS=$(git rev-list master | wc -l) \
git filter-branch --index-filter \
'if [[ ${I} -lt $((NUM_COMMITS - KEEP)) ]]; then
     git rm --cached --ignore-unmatch big_manual.txt;
 fi;
 I=$((I + 1))'

这会在最后10次提交中保留big_manual.txt

话虽如此,就像Charles提到的那样,我不确定这是最好的方法,因为你实际上是通过删除旧版本来撤销VCS的全部内容。

您是否已尝试使用git-gc和/或git-repack优化git存储库?如果没有,那些可能值得一试。

答案 1 :(得分:15)

注意: 这个答案是关于缩短整个项目的历史记录,而不是从旧历史记录中删除单个文件问题是关于!


使用git filter-branch缩短整个项目历史记录的最简单方法是使用移植机制(请参阅repository layout文档)缩短历史:

$ echo "$commit_id" >> .git/info/grafts

其中$commit_id是您想要成为新存储库的根(第一次提交)的提交。使用“git log”或图形历史查看器(如历史记录所需的gitk)查看,然后运行“git filter-branch --all”; git-filter-branch文档中描述了移植物的使用。

或者您可以使用git clone--depth <depth>选项使用浅层克隆



您可以使用移植来删除单个文件的部分历史记录(最初请求的内容),使用下面描述的步骤。此解决方案包含比solution proposed by Dan Moulding更多的步骤,但每个步骤都更简单,您可以使用“git log”或图形历史记录查看器检查中间步骤。

  1. 首先,选择要删除文件的点,然后通过在这些点创建分支来标记这些提交。例如,如果您希望第一次在提交f020285b中显示文件并将其在所有祖先中删除,请使用

    将其标记为祖先(假设这是普通的非合并提交)
    $ git branch cleanup f020285b^
    
  2. 其次,使用git-filter-branch从cleanup开头的历史记录中删除文件(即f020285b^),如git-filter-branch联构帮助页的“示例”部分所示:

    $ git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_manual.txt' cleanup
    

    如果您还要删除所有仅更改为已删除文件的提交,您还可以使用--prune-empty选项git-filter-branch。

  3. 接下来,使用移植机制将历史记录的重写部分与历史记录的其余部分结合起来:

    $ echo $(git-rev-parse f020285b) $(git rev-parse cleanup) >> .git/info/grafts
    

    然后你可以检查histry以检查它是否正确连接。

  4. 最后,使移植物永久化(这将使所有移植物永久化,但我们假设您不使用移植物,否则)使用git-filter-branch,

    $ git filter-branch cleanup..HEAD
    

    并移除移植物(因为它们不再需要)和cleanup分支

    $ rm .git/info/grafts
    $ git branch -d cleanup
    
  5. 最后注意事项:如果删除某些文件的部分历史记录,最好确保没有此文件的项目有意义(例如正确编译)。

答案 2 :(得分:3)

您可能需要考虑使用git submodules。这样,您可以将图像和其他大文件保存在另一个git存储库中,具有源代码的存储库可以引用该另一个存储库的特定修订版。

这将帮助您保持存储库修订同步,因为父存储库包含指向特定子存储库修订的链接。它还允许您删除/重新定义子存储库中的旧版本,而不会影响源代码所在的父存储库 - 子存储库中旧版本的删除不会弄乱父存储库的历史记录,因为您只是更新父存储库中子存储库链接指向的修订版。