How to e.g. change Java package name, over all revisions, while preserving Git history

Recently a customer requested that a piece of software should "move companies" from company A to company B, henceforth appearing as if it'd always been created by company B, and never appear to have been produced by company A at all. (I would surprise you if I say this is not the first time I've received such a request.. or not?)

The simplest way would have been to rename everything in the source code, copy it to a new directory, git init, check it in, throw away the old repository.

I'm a big fan of history in version control systems. Is there a way to change the company's name while preserving history?

After a while of intense Gitting, this is what I came up with. I publish it here in the hope that it will be useful to someone :-)

git filter-branch -f --prune-empty --tree-filter '
  find .                                     \
    -name .git -prune -o                     \
    -exec sh -c "file {} | grep -q text" \;  \
    -exec sed -i ""                          \
      -e "s/Old Company/New Company/g"       \
      -e "s/com.oldcompany/com.newcompany/g" \
      {} \;                                  \
  && mv src/main/java/com/oldcompany src/main/java/com/newcompany
' 

WARNING: This command was written on a Mac. Take out the "" after the -i option if you're on Linux.

This is what's going on:

Good luck with your filtering. What could go wrong?

P.S. I recently created a nerdy privacy-respecting tool called When Will I Run Out Of Money? It's available for free if you want to check it out.

This article is © Adrian Smith.
It was originally published on 1 Feb 2018
More on: VCS | Tools