Skip to content

Git仓库重置历史提交者和邮箱

主要解决 Git 修改用户名,将历史提交中提交者的名字和邮箱也一并修改。

记录

准备

查看日志中已有的用户名和邮箱

Bash
# %aN -> name, %aE -> email
git log --format='%aN <%aE>' | sort -u

几种方式:都会修改提交的 commit-id。

git filter-branch 方式

Bash
#!/bin/sh

# -f 参数
# CORRECT_NAME="github-actions[bot]"
# CORRECT_EMAIL="41898282+github-actions[bot]@users.noreply.github.com"

git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="your-new-name"
CORRECT_EMAIL="[email protected]"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

git-filter-repo方式

需要先安装 git-filter-repo。 参见https://github.com/newren/git-filter-repo

Warning

这个会清空远程仓库信息,需要重新添加。

  • 远程仓库地址恢复
Bash
URL=$(git remote get-url origin)
# 清理……
git remote add origin $URL
git push --all --force
  • 修改步骤
Bash
# 修改邮箱
git filter-repo --email-callback '
    if email in [
        b"[email protected]",
        b"[email protected]",
    ]:
        return b"[email protected]"
    else:
        return email
'

# 非英文的字符需要使用 .encode('utf-8')
# 修改用户名
git filter-repo --name-callback '
    if name in ["旧的名字".encode("utf-8"), b"old-name"]:
        return b"new-name"
    else:
        return name
'

补充

  • 根据提交信息修改用户名和邮箱
Bash
# 过滤信息
git filter-branch -f --env-filter '
    CORRECT_NAME="github-actions[bot]"
    CORRECT_EMAIL="41898282+github-actions[bot]@users.noreply.github.com"
    MESSAGE="Automated Update"

    if git log --format="%B" -n 1 $GIT_COMMIT | grep -q --regexp="$MESSAGE";
    then
        export GIT_COMMITTER_NAME="$CORRECT_NAME"
        export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
        export GIT_AUTHOR_NAME="$CORRECT_NAME"
        export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
    fi
    ' --tag-name-filter cat -- --branches --tags
  • 添加 GPG 签名
Bash
## 添加gpg,-S参数

git filter-branch -f --commit-filter '
    CORRECT_EMAIL="41898282+github-actions[bot]@users.noreply.github.com"

    if [ "$GIT_AUTHOR_EMAIL" = "$CORRECT_EMAIL" ]; then
        git commit-tree -S "$@";
    else
        git commit-tree "$@";
    fi' --tag-name-filter cat -- --branches --tags

Comments