如何压缩Git标签间提交为单条带标签提交并保留共同作者信息
Git仓库提交历史压缩实现方案
操作前请先完整备份仓库,执行git clone --mirror 你的原仓库地址 备份仓库.git,避免操作失误丢失数据。
操作步骤
第一步:获取所有版本tag的正确排序
按版本创建时间升序读取所有tag到数组,确认顺序符合TAG1到TAG6的版本迭代顺序:TAGS=($(git tag -l --sort=creatordate)) # 输出确认tag顺序无误,若顺序不对可将--sort=creatordate替换为--sort=v:refname按语义版本号排序 echo ${TAGS[@]}第二步:构建TAG1的压缩提交
从最早版本开始创建压缩后的根提交,同时收集该版本所有贡献者信息:# 切换到TAG1对应的原始提交 git checkout ${TAGS[0]} # 收集从根提交到TAG1所有贡献者的co-authored-by信息 CO_AUTHORS=$(git log --format='Co-authored-by: %an <%ae>' HEAD | sort -u) # 重置到仓库最早的根提交,暂存所有变更 git reset $(git rev-list --max-parents=0 HEAD) git add . # 生成压缩提交,保留所有贡献者信息 git commit -m "版本 ${TAGS[0]} 正式发布" -m "$CO_AUTHORS" # 强制覆盖原有TAG1标签 git tag -f ${TAGS[0]}第三步:迭代处理其余TAG的压缩提交
遍历所有相邻tag对,将每两个tag之间的所有提交合并为一条,同时保留贡献者信息:# 此处数组下标根据你的tag数量调整,6个tag对应下标0到5,所以循环从1到5 for i in {1..5}; do OLD_TAG=${TAGS[$i-1]} NEW_TAG=${TAGS[$i]} # 切换到当前新版本tag的原始提交 git checkout $NEW_TAG # 软重置到上一个版本的压缩提交,保留当前版本所有代码变更 git reset --soft $OLD_TAG # 收集两个tag区间内所有贡献者信息 CO_AUTHORS=$(git log --format='Co-authored-by: %an <%ae>' ${OLD_TAG}..${NEW_TAG} | sort -u) # 生成当前版本的压缩提交 git commit -m "版本 ${NEW_TAG} 正式发布" -m "$CO_AUTHORS" # 强制覆盖原有新版本tag git tag -f ${NEW_TAG} done第四步:迁移TAG6之后的未打标签提交
将TAG6到当前主分支HEAD之间的所有未打标签提交迁移到新的TAG6提交之后:# 将下方的main替换为你仓库的主分支名,如master OLD_MAIN_HEAD=$(git rev-parse origin/main) # 批量迁移所有未打标签的提交 git cherry-pick ${TAGS[5]}..${OLD_MAIN_HEAD}第五步:验证并推送
- 执行
git log --oneline --graph确认提交历史符合预期,总提交数约15条 - 执行
git diff 原备份仓库的tag提交id 新的同tag提交id确认每个版本的代码内容和压缩前完全一致 - 通知所有协作者之后,强制推送新的主分支和标签到远程仓库:
# 替换为你的主分支名 git push -f origin main git push -f --tags origin- 执行
注意事项
- 若原有tag为带签名的标签,打标签时添加
-s参数重新签名 - 协作者本地仓库需要执行
git fetch origin && git reset --hard origin/main同步新的历史(操作前请告知他们备份本地未提交的修改)
内容的提问来源于stack exchange,提问作者mmix
相关产品推荐
相关产品推荐

