immwind

长风

life, the programming and everything

Using filter-repo to modify git commit history

A few days ago, I found that the git email address for a project was incorrect. Today, I took the opportunity to use the ancestral script to make the modification. However, I received a prompt: "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 instead." Since there is a new command (method), I naturally want to give it a try.

Introduction#

git-filter-repo is a tool written in [[Python]] for filtering and transforming the history of a [[git]] repository. It can perform various operations on commit history, such as deletion, rewriting commit history, and splitting repositories.

Installation#

On macOS, you can install it using [[Homebrew|brew]]:

brew install git-filter-repo

Alternatively, you can install it using [[pip]]:

pip3 install git-filter-repo

Of course, you can also download the source files directly from the repository and run them. The advantage of installation is that it can be used in conjunction with git commands.

Usage#

Here, the main purpose is to modify the email information of historical commits:

git filter-repo --email-callback "return email.replace(b'old@email.com', b'new@email.com')"

Another way is to simultaneously modify the email and name (multiple):

git filter-repo --mailmap mailmap

The content of the mailmap file should be as follows:

<new@email.com> <old@email.com>
new_name <new@email.com> old_name <old@email.com>

Note:

  • The <> symbols are required in --mailmap.
  • The order of email addresses is different between --email-callback and --mailmap.

After completing the modification, if you encounter the prompt "fatal: No configured push destination" during push, you need to reset the remote repository first:

git remote add origin <url>
git push --set-upstream origin master -f

Issues#

After making modifications and pushing them on my local machine, when I tried to pull on the server, I received the following prompt:

hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint: 
hint:   git config pull.rebase false  # merge (the default strategy)
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint: 
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.

I tried adding -f and following the instructions, but it didn't solve the problem. So, I decided to directly delete the .git directory, clone again, and copy the modified files back. Finally, the commit history was consistent.

Information#

Environment#

  • Python 3.10.10
  • GitHub 2.39.2
  • git-filter-repo 2.38.0
  • System: macOS 13.4.1

References#

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.