我需要从一个应该被忽略的旧仓库中删除一些Xcode文件。所以我运行了以下命令
git filter-branch --index-filter 'git rm -f --cached --ignore-unmatch *mode1v3 *pbxuser' HEAD
我的理解是添加--cached不会影响当前的工作目录,但是git也删除了那些匹配的文件。幸运的是我有一个备份(!),但我很好奇为什么会这样做,或者我误解了--cached
的作用?
答案 0 :(得分:4)
罪魁祸首不是git rm
命令。正如你所说,它的--cached
选项确实有效。你可以在一个小的git repo中轻松尝试。
虽然手册页没有提及,但git filter-branch
似乎并未保留您的工作区域。实际上,如果您的工作区域不干净,该命令将拒绝运行,这已经是一个迹象。
但即使文件从工作区域消失,它们也不会从回购中消失。它们不再在您当前分支中的任何提交中。但是,在重写为引用名称空间refs / original /之前,filter-branch商店会引用您的分支。
使用命令git show-ref
查看。
您可以查看旧版本以访问已删除的文件。你可以使用命令
git cat-file blob refs/original/refs/heads/master:foo
获取文件的内容而不检出(使用show-ref显示的引用,foo是所需文件的名称)。有很多可能性
您可以使用gitk --all
浏览重写的和当前的分支,您会发现没有任何内容真的消失。
答案 1 :(得分:1)
git-filter-branch
的行为可能会令人惊讶,正如您所发现的那样 - 当您运行它时,它不会保护您免受意外后果。
相反,我建议使用BFG Repo-Cleaner,这是一种更简单,更快速的替代方案,专门用于从Git历史记录中删除文件。它让您的生活更轻松的一种方式是will not delete, or change in any way,您最近提交的文件 。
您应该遵循usage instructions - 但核心位是这样的:下载BFG's jar(需要Java 6或更高版本)并运行此命令:
$ java -jar bfg.jar --delete-files *{mode1v3,pbxuser} my-repo.git
将删除与您的最新提交中不同的任何与您的最新提交中的表达式匹配的文件。然后,您可以使用git gc
清除死数据:
$ git gc --prune=now --aggressive
BFG的使用通常比git-filter-branch
简单得多 - 这些选项围绕这两种常见用例进行了定制:
完全披露:我是BFG Repo-Cleaner的作者。