gitgit-filter-repo

Using git filter-repo to clean up git history


I have a repository that used to be a monolithic repository, and used to have, let's say, some library, sitting under common/shared/foo subdirectory. Then some people decided to switch to microservices, so they basically made X copies of the repository, and in each of those just deleted all non-relevant files, moved foo contents on the root level (so what used to be under common/shared/foo/src/ is now under src/, etc.; and then just committed it as a single commit (later referred to as "big bang" commit). And then for about a year development occurred within those "mini" repositories.

Now, I'd like to rewrite (clean up) history in such repositories, so I googled a bit and decided to use Git filter-repo for that. However I can't find a combination of options that would treat sub-histories differently: for commits prior to a "big bang" it should only filter (leave in place) commits touching on the common/shared/foo subdirectory; and also for those commits leave all files from under this subdirectory to a root directory; and for all commits after the "big bang" commit, it should just leave all "as is".

Is there a way to achieve this with git filter-repo?


Solution

  • You can list the branches (or any refs) to work on with the --refs option:

    git branch that/point/in/time <commit sha>
    git filter-repo --refs that/point/in/time ...
    

    Once you have rewritten up to that/point/in/time, you can plug the recent history on top of the rewritten sequence:

    # Replace the commit that initially was that/point/in/time with the rewritten one:
    git replace <previous sha> that/point/in/time
    
    # Run git filter-repo --force to rewrite the history of all branches as
    # If they happened on top of the new commit:
    git filter-repo --force
    

    Note: The above command will simply write a new chain of commits, with the content of each commit preserved as is. Inspect your history to see if you need to add some additional edits around the junction.