使用 filter-repo 修改 git 提交记录

2023-07-13

前两天发现有个项目的 git 邮箱写错了,趁今天稍微空些准备祭出祖传的脚本进行修改,谁知出现提示: “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.”。既然有新的命令(方式)自然要尝试一般。

介绍

git-filter-repo

是一个使用 Python 编写,用于过滤和转换 Git 存储库历史记录的工具。可以对提交记录进行各种操作,如删除、重写提交历史、拆分存储库等。

安装

macOS 可以通过 Homebrew 安装:

Terminal window
1
brew install git-filter-repo

或是使用 pip 安装:

Terminal window
1
pip3 install git-filter-repo

当然也可以直接从仓库下载源文件运行,安装的好处是可以结合到 git 命令中使用。

使用

这里主要是对历史提交的邮箱信息进行修改:

Terminal window
1
git filter-repo --email-callback "return email.replace(b'[email protected]', b'[email protected]')"

另一种方式支持同时修改邮箱和姓名 (多个):

Terminal window
1
git filter-repo --mailmap mailmap

对应 mailmap 文件内容:

注:

  • —mailmap 中 <> 符号是必须的
  • —email-callback 和 —mailmap 两种方式的邮箱顺序不一样

修改完成后 push 如果出现: “fatal: No configured push destination” 提示,需要先重新设置远程仓库:

Terminal window
1
git remote add origin <url>
2
git push --set-upstream origin master -f

问题

在本机修改并 push 后,在服务器上执行 pull 时提示:

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

尝试加 -f 和按提示操作之后也没办法解决,索性直接把 .git 目录删除,重新 clone 后拷贝过来后,提交记录总算一致。

信息

环境

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

参考