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
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
|