139 lines
3.4 KiB
Markdown
139 lines
3.4 KiB
Markdown
# 最终修复 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
|
||
```
|
||
|
||
|