首页 > 解决方案 > git:如何从当前不存在的 git 历史记录中删除 *all* 文件?

问题描述

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

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

我的用例是我small从一个单一的存储库(调用它)中分离出一个较小的存储库(调用它monolith)。我想在创建时保留 git 历史记录small,但只保留相关的git 历史记录。

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

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

但是,历史上有大量文件small不再相关,并且它们正在使存储库膨胀。

我想做的是:

  1. 删除所有不需要的文件small
  2. 运行命令以清除我刚刚删除的文件的整个 git 历史记录。

有没有办法用一个命令来做到这一点?或者我是否需要为git filter-branch要删除的每个文件/目录运行一次?

标签: git

解决方案


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

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

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


推荐阅读