编写带默认参数的git-filter-repo Shell脚本及问题排查
批量修改Git提交作者/提交者信息的Shell脚本修复方案
你遇到的报错是因为here-doc语法错误——在cat << EOF后面多写了单引号,导致Shell把后续的Python代码片段当成了要读取的文件名,而非输入内容。同时原脚本里的变量无法在单引号包裹的Python代码中被Shell替换,这也会导致最终执行的filter命令不符合预期。
修正后的完整脚本
#!/bin/bash # 默认参数值 OLD_EMAIL="incorrect@email" NEW_EMAIL="correct@email" NEW_NAME="Correct Name" # 脚本使用说明 usage() { echo "用法: $0 [-o 旧邮箱] [-n 新名称] [-e 新邮箱]" echo "示例: $0 -o wrong@old.com -n \"John Doe\" -e john@new.com" exit 1 } # 解析命令行参数 while getopts ":o:n:e:" opt; do case $opt in o) OLD_EMAIL="$OPTARG" ;; n) NEW_NAME="$OPTARG" ;; e) NEW_EMAIL="$OPTARG" ;; \?) echo "非法选项: -$OPTARG" >&2; usage ;; :) echo "选项 -$OPTARG 需要传入参数" >&2; usage ;; esac done # 移除已解析的参数,检查是否有多余参数 shift $((OPTIND - 1)) if [ $# -gt 0 ]; then echo "意外的多余参数: $*" >&2 usage fi # 构建git filter-repo的回调命令 # 使用here-doc传递Python代码,确保Shell变量能正确替换 FILTER_CMD=$(cat <<EOF if commit.author_email == b'$OLD_EMAIL': commit.author_email = b'$NEW_EMAIL' commit.author_name = b'$NEW_NAME' commit.committer_email = b'$NEW_EMAIL' commit.committer_name = b'$NEW_NAME' EOF ) # 执行修改命令 echo "正在修改仓库中所有提交的作者信息..." git filter-repo --commit-callback "$FILTER_CMD" # 验证修改结果 echo "修改完成,以下是最新的提交日志片段:" git log --oneline --format="%h %an <%ae>" | head -20
关键修改说明
- 修复here-doc语法:删除
<< EOF后的单引号,确保cat读取后续代码片段而非文件名;同时EOF必须顶格书写,避免语法错误。 - 变量替换处理:将Python代码中的字符串从
b"..."改为b'...',让Shell可以正确解析$OLD_EMAIL等变量,把实际值插入到Python代码中。 - 增强参数校验:添加
usage函数,当用户传入非法选项、缺少参数或多余参数时,输出清晰的使用提示。 - 优化结果验证:用精简的
git log格式输出作者信息片段,方便快速确认修改效果。
使用注意事项
- 执行脚本前,确保当前目录是Git仓库根目录,且仓库无未提交修改(建议先备份仓库)。
- 需要提前安装
git-filter-repo工具(部分Git版本默认包含,缺失时可通过包管理器安装,如apt install git-filter-repo或brew install git-filter-repo)。 - 修改完成后,若需同步到远程仓库,需执行强制推送:
git push --force --all(注意:此操作会覆盖远程仓库历史,仅在私有仓库或团队确认后执行)。
内容的提问来源于stack exchange,提问作者DeltaIV
相关产品推荐
相关产品推荐

