git:如何从git历史记录中删除当前不存在的*all*文件



我看过几篇关于如何从所有git历史中删除单个文件的文章和问题。示例:如何从Git存储库的提交历史中删除一个大文件?

我想做的是删除所有文件,这些文件当前不在主分支的头部。

我的用例是将一个较小的存储库(称为small(与一个单片存储库(也称为monolith(分开。我想在创建small时保留git历史记录,但只保留相关的git历史。

首先,我在GitHub上创建了一个新的存储库small。然后,在我的笔记本电脑上,我将它作为一个名为origin-small的远程添加到我的本地monolith存储库中,并将monolith的主分支的当前状态推送到origin-small

然后,我从monolith中删除了远程origin-small,更改了目录,并从GitHub中克隆了small。瞧,我有一份我的原始存储库monolith的副本,里面有它的完整历史。

但是,small的历史记录中有大量文件不再相关,它们正在膨胀回购。

我想做的是:

  1. small中删除所有不必要的文件
  2. 运行一个命令来清除我刚刚删除的文件的整个git历史记录

有没有一种方法可以用一个命令来实现这一点?还是需要为要删除的每个文件/目录运行git filter-branch一次?

我最终使用了git-filter-repo警告:此方法无法更新远程设备上的标记(如果有的话(

  1. 安装git-filter-repo

    brew install git-filter-repo
    
  2. 以镜像形式克隆您想要的回购。

    git clone --mirror <my-repo-url>
    
  3. 输入repo目录。

    cd <my-repo-name>
    
  4. 分析repo以识别历史记录中但已不存在的所有文件。

    git filter-repo --analyze
    
  5. analysis输出目录中,将有一个名为path-deleted-sizes.txt的文件,该文件包含一个列表,列出了在某个时刻提交的、后来被删除的、但仍存在于git历史中的所有文件。

    创建一个没有标题和其他列的新文件。

    tail +3 ./filter-repo/analysis/path-deleted-sizes.txt 
    | tr -s ' ' 
    | cut -d ' ' -f 5- 
    > ./filter-repo/analysis/path-deleted.txt
    
  6. 清除所有不再存在的文件的git历史记录。这还将清理脏提交,删除空提交,并为您重新压缩所有内容。

    git filter-repo --invert-paths --paths-from-file ./filter-repo/analysis/path-deleted.txt
    
  7. 清理./filter-repo目录,否则您将无法推送您的更改。

    rm -rf ./filter-repo
    
  8. 强制将所有引用推到原点。它会强制推送,即使命令没有指示它。此外,它会更新远程上的所有分支,这很方便。如果你在GitHub/Bitbucket等中的一些分支上启用了分支保护。,那么你需要允许用力推。如果您发现某些refs无法被强制推送,您可以随时重新运行此命令。

    git push
    

列出旧提交中存在的所有文件。

git rev-list HEAD | sed 1d | xargs -i git ls-tree -r {} --name-only | sort -u

列出头中存在的所有文件。

git ls-tree -r HEAD --name-only | sort -u

获取头中不存在的文件(引用(。

files=$(comm -23 <(git rev-list HEAD | sed 1d | xargs -i git ls-tree -r {} --name-only | sort -u) <(git ls-tree -r HEAD --name-only | sort -u))

将不可见的字符(我猜是新行(替换为空格,否则会导致git filter-branch中出现错误。

lostfiles=$(echo $files | sed -e 's/s/ /g')

从历史记录中删除lostfiles

git filter-branch -f --tree-filter "rm -rf ${lostfiles}" --prune-emtpy

可以将它们组合为一个命令,但我不知道是否会有任何性能问题,所以我更喜欢单独的命令。

最新更新