git删除文件的最旧版本

neo*_*eye 20 git

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

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

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

git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_manual.txt' HEAD
Run Code Online (Sandbox Code Playgroud)

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

Dan*_*ing 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))'
Run Code Online (Sandbox Code Playgroud)

这将保留big_manual.txt在最近10次提交中.

话虽这么说,就像Charles提到的那样,我不确定这是最好的方法,因为你实际上是通过删除旧版本来撤销VCS的重点.

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


Jak*_*ski 15

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


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

$ echo "$commit_id" >> .git/info/grafts
Run Code Online (Sandbox Code Playgroud)

$commit_id您希望成为新存储库的根(第一次提交)的提交在哪里.使用"git log"或图形历史查看器(如历史记录所需的gitk)查看,然后运行"git filter-branch --all"; git-filter-branch文档中描述了使用移植物.

或者你可以使用浅克隆使用--depth <depth>的选项git的克隆.



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

  1. 首先,选择要删除文件的点,并通过在这些点创建分支来标记这些提交.例如,如果您希望第一次在提交中显示文件f020285b并将其在所有祖先中删除,请将其标记为祖先(假设这是普通的,非合并提交)

    $ git branch cleanup f020285b^
    
    Run Code Online (Sandbox Code Playgroud)
  2. 其次,使用git-filter-branch 从cleanup(即f020285b^)开始的历史记录中删除文件,如git-filter-branch联机帮助页的"示例"部分所示:

    $ git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_manual.txt' cleanup
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    $ echo $(git-rev-parse f020285b) $(git rev-parse cleanup) >> .git/info/grafts
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    $ git filter-branch cleanup..HEAD
    
    Run Code Online (Sandbox Code Playgroud)

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

    $ rm .git/info/grafts
    $ git branch -d cleanup
    
    Run Code Online (Sandbox Code Playgroud)

最后说明:如果删除某些文件的部分历史记录,最好确保没有此文件的项目有意义(例如正确编译).