删除所有 Git 提交中除选定文件之外的所有文件

remove all but selected files in all Git commits

在 Git 历史记录的所有其他文件中,我有几个 "interesting" 文件(我接触过)。我想发布 "interesting" 文件,仅将它们的历史记录作为 Git 回购,没有任何其他文件出现在这个回购历史的任何地方。

如何为git filter-branch --index-filter编写智能脚本? (或者至少对于 git filter-branch --tree-filter,这是不受欢迎的,因为它更慢,而且我保存的树很大。)

请注意,我的问题与人们问的最常见的类似问题有点不同 12如何从 Git history? 我要去掉补码,保留具体文件。

因此,git filter-branch --index-filter 脚本中的棘手部分是从索引中获取文件列表,过滤掉特定的文件,然后删除生成的列表。

我已经将其实现为一个单独的可执行脚本 git-update-index-keeping-only;这是粗略的实现:

git ls-files --full-name \
| fgrep -v -x -f <(echo "$FILELIST") \
| xargs git rm --cached "$@" --

我没有想太多文件名中的换行符和空格会发生什么(空格肯定是 xargs 的问题,除非它被告知为每个参数再次调用命令,这我不是为了效率而做的)。

在另一个对我的用例有用的脚本中写下了示例用法:获取有趣的列表,因为在两次提交之间的差异中修改或添加了那些(例如,"upstream" 提交和您的最后一次提交最重要的是)。

git-filter-only-files-modified-since;它的本质是这样的:

FILES="$(git diff-tree "$SINCE": HEAD: \
   -r --name-only --diff-filter=MACRT)"
export FILES
git filter-branch \
   --index-filter 'echo "$FILES" | git-update-index-keeping-only -q'