In my Flutter project, I had accidentally committed the iOS build into my local git history. When I tried to push to GitHub, it failed with an error telling me that my commits contain a large file (over 100 MB):
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com
If only the latest commit contained that file, I might have easily amended the commit. However, I had committed it a few commits earlier. So I looked at my alternatives.
One was to use interactive rebase (doc). But that means I have to manually look at each commit one by one to see where the changes were made. Let's say I had introduced the file some 10 commits ago, and even modified it in some other commits. Then the process would be quite tedious.
Then I stumbled upon https://git-scm.com/docs/git-filter-branch. Despite the scary warnings, it worked greated in my case:
% git filter-branch --tree-filter 'rm -f ios/Runner.ipa' HEAD
WARNING: git-filter-branch has a glut of gotchas generating mangled history
rewrites. Hit Ctrl-C before proceeding to abort, then use an
alternative filtering tool such as 'git filter-repo'
(https://github.com/newren/git-filter-repo/) instead. See the
filter-branch manual page for more details; to squelch this warning,
Proceeding with filter-branch...
Rewrite 672e5f7bf76b070e929b87de5b1a42e4ace5252f (124/124) (18 seconds passed, remaining 0 predicted)
Ref 'refs/heads/master' was rewritten
% git push origin HEAD -f
It took 18 seconds for a history of 124 commits, and that's without using any kind of filtering.
The doc recommends using git-filter-repo instead, but then I'd need to install a new tool. My use case was simple enough that it was not necessary.