git-filter-repo

本文主要介绍了如何使用git-filter-repo修改commit历史。

介绍

git-filter-repo是官方推荐用于修改commit历史的小工具,详情参见:https://github.com/newren/git-filter-repo/tree/main/contrib/filter-repo-demos

依赖条件

要使用 git-filter-repo工具,需要做如下准备:

  • git >= 2.22.0 at a minimum

  • some features require git >= 2.24.0

  • python3 >= 3.5

下载

git clone https://github.com/newren/git-filter-repo.git

安装

cd git-filter-repo/
sudo cp git-filter-repo /usr/local/bin
重要

修改了提交的邮箱或者message之后会生成新的commit,分支也会指向新的commit,建议修改提交邮箱或者message之前,先创建新分支保存当前分支指向,例如git branch tmp。

修改提交邮箱

执行方式解析

以修改邮箱为例该工具执行模式如下:

git-filter-repo --email-callback 'BODY'会生成一个python call_back函数并被git-filter-repo调用。

def email_callback:
      BODY

操作步骤

例如要将master分支的最近 2 个提交的邮箱后缀由alibaba-inc.com改为example.com则使用下述命令:

git-filter-repo --email-callback 'return email.replace(b"alibaba-inc.com", b"example.com")' --force  --refs master~2..master

其中加 --force 是因为 git-filter-repo 默认只能对刚 clone 下来的仓库进行修改,否则需要加 --force 强制进行。结果如下:

高的 - 2024-11-18T145814

可以看到 master 分支的 commit 的邮箱后缀由alibaba-inc.com改为了example.com。注意,由于邮箱修改了,对应的 commit ID 也变了。

如需修改当前分支全部commit 的邮箱信息,则去掉master~2..master直接使用以下命令:

git-filter-repo --email-callback 'return email.replace(b"alibaba-inc.com", b"example.com")' --force  --refs master

修改提交 message

接着上一个示例,方法与修改提交邮箱相似,需使用--message-callback命令,例如要将上述 master 分支最近 1 个 message 中的“3”改为”hi”:

git-filter-repo --message-callback 'return message.replace(b"3", b"hi")' --force  --refs master~1..master

执行后可以看到①处最近 1 次提交的 message 已经从原来的“3”变成了“hi”:

高的 - 2024-11-18T145911

高阶版修改

例如期望在master分支最近 1 次提交message之前加上“bugfix: ”如何处理呢?请参考如下命令:

git-filter-repo  --message-callback '
    message=b"bugfix: " + message
    return message
' --refs master~1..master --force

执行效果如下,可以看到②处的 message 自动增加了“bugfix:”前缀:

高的 - 2024-11-18T150018

总之,无论是修改提交邮箱还是提交message都可以使用python编写对应的call-back函数来定义修改规则。

更多高级功能,请参见 https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html