3.4 KiB
3.4 KiB
最终修复 Change-Id 重复问题
问题分析
多个提交使用了相同的 Change-Id,导致 Gerrit 拒绝推送。
解决方案
方法一:使用每个提交的 SHA1 作为 Change-Id(最简单可靠)
每个 Git 提交的 SHA1 都是唯一的,直接使用它作为 Change-Id:
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:
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
方法三:使用脚本批量处理(自动化)
如果提交很多,使用这个脚本:
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
推荐操作(最简单)
直接执行这个命令:
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:
# 检查所有提交的 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