I have a repository that used to be a monorepo, 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" repos.

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? Thanks

1

Best Answer


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.