# 最终修复 Change-Id 重复问题 ## 问题分析 多个提交使用了相同的 Change-Id,导致 Gerrit 拒绝推送。 ## 解决方案 ### 方法一:使用每个提交的 SHA1 作为 Change-Id(最简单可靠) 每个 Git 提交的 SHA1 都是唯一的,直接使用它作为 Change-Id: ```bash cd /d/zhini/zhini_im # 1. 创建备份 git branch backup-before-final-fix # 2. 为所有提交重新生成 Change-Id(使用每个提交的 SHA1) git filter-branch -f --msg-filter ' # 读取并移除旧的 Change-Id cat | grep -v "^Change-Id:" # 使用当前提交的 SHA1 生成唯一的 Change-Id echo "" echo "Change-Id: I$(git rev-parse HEAD)" ' --tag-name-filter cat -- --branches --tags # 3. 验证 git log --format='%H' | while read commit; do changeid=$(git log -1 --format='%B' "$commit" | grep "^Change-Id:" | head -1 | cut -d' ' -f2) echo "$commit $changeid" done | sort -k2 | uniq -d -f1 # 如果没有输出,说明所有 Change-Id 都是唯一的 # 4. 推送 git push gerrit HEAD:refs/for/master ``` ### 方法二:使用 git rebase 让 hook 自动生成(最标准) 这个方法会让 commit-msg hook 为每个提交自动生成正确的 Change-Id: ```bash cd /d/zhini/zhini_im # 1. 确保 hook 已安装 mkdir -p .git/hooks curl -o .git/hooks/commit-msg http://101.43.95.130:8080/tools/hooks/commit-msg chmod +x .git/hooks/commit-msg # 2. 创建备份 git branch backup-before-rebase # 3. 从根提交开始 rebase git rebase -i --root # 在编辑器中: # - 将所有 'pick' 改为 'reword' # - 保存并关闭(:wq) # # 对每个提交: # - 提交信息编辑器会自动打开 # - 不要修改任何内容,直接保存退出(:wq) # - commit-msg hook 会自动为每个提交生成唯一的 Change-Id # - 继续下一个提交(git rebase --continue) # 4. 推送 git push gerrit HEAD:refs/for/master ``` ### 方法三:使用脚本批量处理(自动化) 如果提交很多,使用这个脚本: ```bash cd /d/zhini/zhini_im # 创建备份 git branch backup-before-script-fix # 执行批量修复 git filter-branch -f --msg-filter ' # 读取原始提交信息 ORIGINAL=$(cat) # 移除所有 Change-Id 行 CLEAN=$(echo "$ORIGINAL" | grep -v "^Change-Id:") # 输出清理后的内容 echo "$CLEAN" | sed -e :a -e "/^\$/{\$!N;ba}" -e "s/\n\$//" # 添加新的 Change-Id(使用提交的 SHA1) echo "" echo "Change-Id: I$(git rev-parse HEAD)" ' --tag-name-filter cat -- --branches --tags # 验证并推送 git push gerrit HEAD:refs/for/master ``` ## 推荐操作(最简单) 直接执行这个命令: ```bash cd /d/zhini/zhini_im # 一步完成:移除所有旧的 Change-Id,为每个提交使用其 SHA1 生成新的 git filter-branch -f --msg-filter 'cat | grep -v "^Change-Id:" && echo "" && echo "Change-Id: I$(git rev-parse HEAD)"' --tag-name-filter cat -- --branches --tags # 推送 git push gerrit HEAD:refs/for/master ``` ## 如果还是有问题 检查是否所有提交都有 Change-Id: ```bash # 检查所有提交的 Change-Id git log --format='%H' | while read commit; do changeid=$(git log -1 --format='%B' "$commit" | grep "^Change-Id:" | head -1 | cut -d' ' -f2) if [ -z "$changeid" ]; then echo "缺少 Change-Id: $commit" else echo "$commit: $changeid" fi done # 检查重复的 Change-Id git log --format='%H' | while read commit; do git log -1 --format='%B' "$commit" | grep "^Change-Id:" | head -1 | cut -d' ' -f2 done | sort | uniq -d ```