Files
gerrit/最终修复Change-Id方案.md
2025-12-22 17:12:39 +08:00

3.4 KiB
Raw Permalink Blame History

最终修复 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