【问题标题】:Remove deleted files from git history从 git 历史记录中删除已删除的文件
【发布时间】:2012-05-20 18:42:48
【问题描述】:

我正在尝试从我的 git 存储库中拆分一个子项目。 然而不像在 Detach (move) subdirectory into separate Git repository 我在它自己的子目录中没有它(并且将其移入并执行上述操作只会产生移动后的历史记录)。

我已经将要从中拆分子项目的分支克隆到它自己的存储库中,并删除了子项目未使用的所有内容,所以基本上我可以将其用作我的子项目的存储库。

现在我想删除所有不再在此存储库中的文件的历史记录,以便只保留使其成为后代的文件的文件历史记录。

我认为 git-filter-branch 一定可以,但我不知道如何

在此先感谢

【问题讨论】:

标签: git version-control git-filter-branch


【解决方案1】:

Here are some instructions to do what you want.

这将删除file_to_remove:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_to_remove' --prune-empty -- --all

【讨论】:

  • 问题是我只想保留工作目录中的文件及其历史记录,并让 git 忘记所有其他文件。用上面的命令先找到所有已删除的文件再删除会很麻烦,这就是为什么即使我发现它也没多大用处
  • 请注意,您可以对整个目录使用git rm -r,递归删除。
  • @Oyvind 使用git rm -r 只会从工作目录中删除一个文件/目录,而不会删除该文件/目录的任何历史记录。它只会将删除添加到历史记录的顶部。
【解决方案2】:

好的,现在我正在尝试使用以下技术,如果它有效,将报告它,因为它似乎运行了很长时间: 在克隆存储库上的 zsh 或 bash 上

git log --diff-filter=D --summary <start_commit>..HEAD | egrep -o '*[[:alnum:]]*(/[[:alnum:].]*)+$' > deleted.txt

获取所有已删除的文件

for del in `cat deleted.txt`
do
    git filter-branch --index-filter "git rm --cached --ignore-unmatch $del" --prune-empty -- --all
    # The following seems to be necessary every time
    # because otherwise git won't overwrite refs/original
    git reset --hard
    git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
    git reflog expire --expire=now --all
    git gc --aggressive --prune=now
done;

这可能对您的数据造成极大的危害,因此请仅尝试克隆。

【讨论】:

  • 你最终发现了什么?
  • 它看起来运行如此缓慢的原因是因为您正在运行git filter-branch 命令每个文件一次,以及一堆其他命令(git gc 运行起来既不便宜也不快速)而不是对所有文件运行一次,因此它可能效率极低。请参阅New repo with copied history of only currently tracked files 的 cmets。
  • 推送到 github 或 gitlab 会清理远程仓库吗?
猜你喜欢
  • 2012-12-05
  • 2014-06-19
  • 2020-03-20
  • 1970-01-01
  • 1970-01-01
  • 2017-10-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-31
相关资源
最近更新 更多