如何从所有的git提交中删除索引中文件的所有出现 [英] How to remove all occurences of a file in index, from all git commits

查看:703
本文介绍了如何从所有的git提交中删除索引中文件的所有出现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

第一次在这里使用git。我不小心使用了没有.gitignore文件的git init,所以我在提交中有一堆gradle /和build / files。我正在使用git ls-tree -r master来显示索引中的所有文件。除了检出每一个前面的提交,并使用git rm --cached删除所有不必要的构建和gradle文件,我如何通过所有以前的提交删除它的所有出现?

编辑:有没有办法删除所有提交中的每个目录和文件,只保留src目录?

解决方案

您可能确实希望过滤分支命令变基。无论哪种方式,都需要注意以下几项:


  • 您无法更改任何 现有的提交, em> ever 。

  • 因此,rebase和filter-branch都不会。相反,他们会复制提交。现在你有两倍的提交!等等,什么?!

  • 但是Git可以并且将最终移除它所称的未引用对象(提交及其相应文件),并且您可以加速


    所以这就是rebase和filter-branch的作用:它们复制提交,并在提交之前副本,允许一些更改。然后,在提交了(略有不同的)副本后,他们将引用 - 分支和标签名称 - 移动到副本中。

    记住,还有几个项目需要考虑:




    • 只有过滤分支复制和移动标记,并且只有在您提供一个 - 标签过滤器。 (如果你没有标签,显然这没什么关系。)而且,当过滤器分支副本签名带注释的标签时,它会删除它们的签名:它们变成无符号。否则,它将不得不让你手动重新签名它们,并且filter-branch被设计为完全自动化。

    • 因为filter-branch被设计为自动化的,并且因为它被设计为能够在存储库中的每个提交上运行,它(a)往往是缓慢的,并且(b)有许多复杂的选项来加速它。如果你没有那么多的提交,这不是什么大问题。如果你这样做,它会学习如何使用它的许多选项来加速它。

    • 因为这两个命令复制提交,如果其他人有一个版本库的副本,也为他们做了一堆工作:他们需要切换到副本。如果他们不这样做,他们可以重新引入所有原始提交,然后回到原来的两倍。


    现在您已准备好链接问题及其筛选器分支答案。有关使用 - 标记的说明,请参阅其他答案以了解相关问题

    请注意 git rm -f --cached --ignore-unmatch 可用于目录(或文件夹)名称以及纯文件名。可以使用 - 树结构过滤器(在第二个链接页面的其他答案中提及)来代替 - index-filter ,对于复杂的操作比较方便,但它比较慢(确切的放缓因操作系统,回购大小,固态硬盘与旋转介质存储等而异,但是比起使用 - index-filter 大约慢100倍是一个好的开始估计。)


    First time using git here. I accidentally used "git init" without a .gitignore file so I have a bunch of gradle/ and build/ files in my commits. I am using "git ls-tree -r master" to show all files in the index. Instead of checking out every single previous commit and using "git rm --cached " to remove all the unnecessary build and gradle files, how do I remove all occurences of it through all previous commits?

    Edit: Is there a way to remove every directory and files in all commits and only keep the src directory?

    解决方案

    You probably really do want the filter-branch command rather than rebase. Either way there are several items to be aware of:

    • You can't change any existing commits, ever.
    • Therefore, both rebase and filter-branch don't. Instead, they copy commits. Now you have twice as many commits! Wait, what?!
    • But Git can and will—eventually—remove what it calls unreferenced objects (commits and their corresponding files), and you can speed this up in various ways if necessary.

    So this is what both rebase and filter-branch do: they copy the commits, and before committing the copy, allow some change(s). Then, having committed the (slightly different) copies, they move the references—the branch and tag names—to the copies.

    With that in mind, there are several more items to consider:

    • Only filter-branch copies and moves tags, and it only does so if you provide a --tag-filter. (If you have no tags, this does not really matter, obviously.) And, when filter-branch copies signed annotated tags, it ditches their signatures: they become unsigned. Otherwise it would have to pester you to manually re-sign them all, and filter-branch is designed to be fully automated.
    • Because filter-branch is designed to be automated, and because it is designed to be able to run on every commit in a repository, it (a) tends to be slow and (b) has a lot of complicated options meant to speed it up. If you don't have that many commits, this is not that big a deal. If you do, it pays off to study how to use its many options to speed it up.
    • Because both commands copy commits, if anyone else has a copy of the repository, you're making a bunch of work for them too: they need to switch over to the copies. If they don't, they can re-introduce all the original commits, and then you are back to having twice as many.

    Now you're ready for the linked question and its filter-branch answer. See this other answer to a related question as well, though, for instructions on using --tag-name-filter and some of the speed-up options.

    Note that git rm -f --cached --ignore-unmatch works on directory (or "folder") names as well as on plain file names. The --tree-filter (mentioned in other answers on the second-linked page) can be used instead of the --index-filter, and it's more convenient for complex operations, but it is much slower (exact slowdown varies based on OS, size of repo, SSD vs spinning-media storage, etc., but "about 100x slower" is a good starting estimate) than using the --index-filter.

    这篇关于如何从所有的git提交中删除索引中文件的所有出现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆