Daniel Tull: Today I Learned

Using git filter-repo to rename a directory for all commits in a branch

Tuesday, 11 July 2023

At work, we’ve been debating the location of where to put our internal Swift packages. Before this decision had been made, I’d created a new package in our repository, but had guessed the incorrect location for the package to live.

I could move the package and make a new commit, however it hasn’t been merged into our main branch yet and I think it’s nicer if it looks like it was always in the correct location. Plus, I know this kind of thing is definitely possible with git.

As I rarely do this kind of procedure, it always involves one or two searches leading to Stack Overflow before I remember the command: git filter-branch. Typing this into the terminal provides the following, somewhat alarming message.

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, set FILTER_BRANCH_SQUELCH_WARNING=1.

Having already seen some Stack Overflow responses say filter-branch is “discouraged” and to use git filter-repo instead, I find that it can be installed using Homebrew:

brew install git-filter-repo

A little reading of the documentation shows that I can get the command to only filter through the references in my current branch using the --refs option and I can provide the old and new locations to the --path-rename option:

git filter-repo --refs develop..dt/my/branch --path-rename Old/Path:New/Path

It’s much easier than I remember filter-branch being!