【git的摸鱼技巧】之工欲善其事 📅 2026/7/4 20:39:51 【git的摸鱼技巧】之工欲善其事 —— Git Cherry-pick 操作与常见问题处理指南增强版目录子模块添加失败“已经存在于索引中”合并冲突导致索引损坏子模块内文件无法直接 add 到主仓库分支迁移将旧仓库的本地分支导入新仓库远程分支在本地可见但服务器上不存在拉取远程分支失败“Couldn’t find remote ref breach”CMake 构建时子模块目录缺少 CMakeLists.txt安装时找不到配置文件合并另一个仓库远程分支的某一个提交跨仓库标签同步1.74 → 1.75补丁应用与冲突解决验证同步是否彻底常见错误及解决办法操作前备份总结1. 基本用法# 应用一个或多个提交gitcherry-pickcommit1commit2...# 应用一个提交范围不包含起始提交gitcherry-pickolder-commit..newer-commit# 应用更改但不自动提交可合并多个提交的改动gitcherry-pick-ncommit# 允许生成空提交通常不推荐gitcherry-pick --allow-emptycommit2. 常见错误与解决2.1 “一个拣选或还原操作已在进行”错误信息error: 一个拣选或还原操作已在进行 提示尝试 git cherry-pick (--continue | --quit | --abort)原因上一次 cherry-pick 未正常结束可能因冲突或空提交而暂停。解决方法场景命令说明放弃操作回到操作前状态git cherry-pick --abort推荐干净回退已解决冲突继续操作git add 文件→git cherry-pick --continue继续后续提交退出但保留工作区状态git cherry-pick --quit不常用保留索引和工作区2.2 空提交Empty Commit现象无文件要提交干净的工作区 之前的拣选操作现在是一个空提交... 如果您想跳过这个提交使用命令git reset 然后执行 git cherry-pick --continue原因该提交的变更内容已存在于当前分支应用后没有产生实际改动。解决方法gitresetgitcherry-pick--continue或直接跳过若 Git 支持gitcherry-pick--skip注某些旧版本 Git 可能不支持--skip请使用reset--continue。2.3 冲突Conflict现象cherry-pick 过程中提示冲突并列出冲突文件。解决方法# 1. 手动编辑冲突文件解决冲突vim冲突文件# 2. 标记已解决gitadd冲突文件# 3. 继续gitcherry-pick--continue# 或放弃本次操作gitcherry-pick--abort3. 连续 cherry-pick 多个提交Git 支持一次指定多个提交按顺序依次应用。gitcherry-pick abc123 def456如果中间某个提交遇到空提交或冲突操作会暂停需要人工处理后再用--continue继续。处理完当前问题后Git 会自动应用后续提交直至全部完成。典型工作流示例# 1. 开始 cherry-pickgitcherry-pick abc123 def456# 2. 若遇空提交按提示处理gitresetgitcherry-pick--continue# 3. 若遇冲突解决后继续vim冲突文件gitadd冲突文件gitcherry-pick--continue# 4. 完成所有提交后查看状态gitstatus4. 跨仓库 Cherry-pick从另一个仓库的远程分支中 cherry-pick 某个特定提交。操作步骤# 1. 添加远程仓库并获取最新信息gitremoteaddremote-name仓库URLgitfetchremote-name# 2. 查看远程分支的提交历史找到目标 commitgitlogremote-name/branch--oneline# 3. 切换到目标本地分支不存在则创建gitcheckout-blocal-branch# 4. 应用指定提交gitcherry-pickcommit-hash# 5. 若遇冲突解决后继续gitadd.gitcherry-pick--continue# 6. 完成后可推送gitpush-uoriginlocal-branch完整示例gitfetch firstgitlog first/qicongjie--oneline# 输出abc1234 Fix something# def5678 Update configgitcheckout first_devgitcherry-pick abc12345. 其他与 Cherry-pick 同步的方法对比当 cherry-pick 单个提交不适合时可考虑以下替代方案场景推荐方法保留历史跨仓库同步全部代码git merge --allow-unrelated-histories✅ 是跨仓库同步按补丁git format-patchgit am✅ 是跨仓库同步仅代码git diffgit apply❌ 否应用外部补丁文件git am patch-file✅ 是仅应用代码差异git apply patch-file❌ 否本地分支迁移git bundle✅ 是本地分支迁移添加本地路径为远程✅ 是format-patch am 方式# 在源仓库生成补丁gitformat-patch--stdout1.74..1.75changes.patch# 在目标仓库应用补丁gitamchanges.patchdiff apply 方式不保留历史# 生成差异gitdiff1.741.75full.patch# 应用差异gitapply full.patch# 若冲突使用 --reject 生成 .rej 文件gitapply--rejectfull.patch6. 跨仓库标签同步无共同历史场景当需要将仓库 A 的标签1.741.75之间的修改同步到仓库 B无共同历史时准备工作cd/path/to/repo-Bgitremoteaddold-repo仓库A的URLgitfetch old-repo--tags方法一merge保留完整历史gitmerge --allow-unrelated-histories refs/tags/1.75方法二bundle适用于未推送的分支# 在旧仓库中gitbundle create myPro.bundle myPro# 在新仓库中gitbundle unbundle myPro.bundlegitcheckout-bmyPro FETCH_HEAD方法三添加本地路径为远程gitremoteaddold-local /path/to/old-repogitfetch old-localgitcheckout-bmyPro old-local/myProgitremote remove old-local7. 补丁应用冲突处理git am 冲突# 查看失败补丁内容gitam --show-current-patch# 手动编辑冲突文件后标记已解决gitadd冲突文件gitam--continue# 跳过当前补丁谨慎gitam--skip# 放弃整个 am 操作gitam--abortgit apply 冲突# 使用 --reject 选项生成 .rej 文件gitapply--rejectfull.patch# 根据 .rej 文件手动修改代码然后删除 .rej 文件rm-f*.rejgitadd.gitcommit-mApply changes8. 验证同步是否彻底# 直接对比当前分支与目标标签/提交gitdiffrefs/tags/1.75# 对比期望差异与实际差异gitdiff1.741.75expected.patchgitdiff1.74HEADactual.patchdiff-uexpected.patch actual.patch# 忽略空白差异gitdiff--ignore-space-change1.741.75expected.patchgitdiff--ignore-space-change1.74HEADactual.patch无输出表示完全一致。9. 操作前备份gitbranch backup-before-sync10. 完整错误参考表错误信息原因解决方法一个拣选或还原操作已在进行上次 cherry-pick 未正常结束--abort或--continue无文件要提交干净的工作区空提交已存在相同改动git reset→--continue冲突代码冲突解决后git add→--continuefatal: 有歧义的参数标签引用格式错误使用refs/tags/或提交哈希error: 打补丁失败补丁上下文不匹配手动修改文件后--continueCouldnt find remote ref远程无此分支检查git branch -r从本地恢复不能打开 .git/FETCH_HEAD: 权限不够文件所有者错误sudo chown -R $(whoami) .gitmerge: xxx - 不能合并当前不在分支上先切换分支11. 注意事项空提交通常表示该改动已存在跳过即可无需强行保留空提交。连续 cherry-pick 时提交顺序影响最终结果建议从旧到新依次应用。若出现反复的空提交先用git show commit查看该提交的实际内容确认是否已包含。若冲突太多可考虑使用git merge或git rebase替代 cherry-pick。操作前务必备份当前分支。处理子模块时务必确保索引干净及时提交.gitmodules的更改。合并冲突导致索引损坏时优先尝试git merge --abort或git reset --hard HEAD。远程跟踪引用无效时使用git remote prune origin清理。12. 命令速查命令说明git cherry-pick commit应用指定提交git cherry-pick -n commit应用但不自动提交git cherry-pick --allow-empty允许空提交git cherry-pick --skip跳过当前提交git cherry-pick --abort放弃操作回到操作前状态git cherry-pick --quit退出操作保留工作区和索引git cherry-pick --continue解决冲突/空提交后继续git am patch-file应用补丁保留历史git apply patch-file应用差异不保留历史git format-patch range生成补丁文件git merge --allow-unrelated-histories合并无共同历史的分支git bundle打包分支迁移git remote prune origin清理无效远程引用