使用git filter-branch重写仓库历史时遇空身份名错误的排查求助
首先可以明确:这个问题大概率和你使用的Git 2.7.4版本有关——这个版本的git filter-branch存在一些身份信息处理的bug,在重写某些提交时可能会丢失作者/提交者信息,导致出现<>空身份的错误。之前其他机器操作正常,很可能是因为那些机器的Git版本更高,已经修复了这类问题。
下面是具体的排查和解决思路:
1. 优先升级Git版本
Git在2.8及以上版本中修复了不少filter-branch的已知问题,包括身份信息丢失的场景。对于Ubuntu 16.04,你可以通过PPA来升级Git:
sudo add-apt-repository ppa:git-core/ppa sudo apt update sudo apt install git
升级完成后再重新执行你的filter-branch命令,大概率能直接解决问题。
2. 临时修复:用--env-filter补全身份信息
如果暂时无法升级Git,可以在filter-branch命令中加入--env-filter,强制为有问题的提交设置正确的身份信息,或者全局覆盖身份变量避免空值:
方案A:仅修复特定的空身份提交
针对那个出现错误的提交1acdc25e87c404e974610b9517f62b4127c3ccac,直接在过滤时补全它的身份:
git filter-branch --env-filter ' if [ "$GIT_COMMIT" = "1acdc25e87c404e974610b9517f62b4127c3ccac" ]; then export GIT_AUTHOR_NAME="My Name" export GIT_AUTHOR_EMAIL="myEmail@mydomain.com" export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME" export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL" fi ' --tree-filter 'rm -f -R a_folder' -- --all
方案B:全局强制设置身份变量
如果不确定还有没有其他潜在的空身份提交,可以直接让filter-branch使用你当前Git配置的身份信息来覆盖所有提交的身份(不会影响原提交的正确性,只是确保重写时不会出现空值):
git filter-branch --env-filter ' export GIT_AUTHOR_NAME="$(git config user.name)" export GIT_AUTHOR_EMAIL="$(git config user.email)" export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME" export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL" ' --tree-filter 'rm -f -R a_folder' -- --all
3. 提前修复空身份提交
你也可以先单独修复那个存在空身份的提交,再执行历史重写:
- 找到该提交的父提交(可以用
git show 1acdc25e87c404e974610b9517f62b4127c3ccac --pretty=format:%P获取) - 执行交互式变基:
git rebase -i <父提交哈希> - 在弹出的编辑界面中,将该提交前的
pick改为edit - 修改提交身份:
git commit --amend --author="My Name <myEmail@mydomain.com>" - 完成变基:
git rebase --continue - 再执行你的
filter-branch命令
不过这种方法适合提交链较短的场景,如果仓库提交很多,还是用--env-filter更高效。
4. 检查Git身份配置
先确认你的Git全局或仓库级身份配置是否正确:
# 检查全局配置 git config --global user.name git config --global user.email # 检查当前仓库配置 git config user.name git config user.email
如果配置为空,先设置好:
git config --global user.name "My Name" git config --global user.email "myEmail@mydomain.com"
虽然这不一定能直接解决filter-branch的bug,但能避免其他潜在的身份问题。
内容的提问来源于stack exchange,提问作者alexmogavero

