Git Cherry-pick、冲突处理、拆分提交与签名实践总结
本文整理了关于批量 cherry-pick、冲突处理、提交拆分、签名补充以及代码历史追踪的常用操作。
批量 Cherry-pick 与提交压缩
从文件读取 Commit 列表
假设 commits.txt 内容如下:
a1b2c3d
d4e5f6g
h7i8j9k
保留原提交:git cherry-pick $(cat commits.txt)
将多个提交合并为一个提交:
git cherry-pick -n $(cat commits.txt)
git commit -m "backport selected commits"
对于大量提交,建议使用脚本:
while read commit; do
git cherry-pick -n "$commit" || exit 1;
done < commits.txt
Cherry-pick 冲突处理
发生冲突后查看状态:git status
解决冲突文件中的:
<<<<<<< HEAD
=======
>>>>>>> commit
解决完成后: git add <file>, 继续执行:git cherry-pick --continue。
如果使用 -n 且状态丢失,可通过命令确认:git ls-files -u
查看是否仍存在未解决冲突。
Rerere 自动复用冲突解决
如果出现:
Resolved '<file>' using previous resolution.
说明 Git 自动复用了之前的冲突解决结果。
查看状态:git rerere status,查看差异:git rerere diff。
忘记某个文件的历史解决方案: git rerere forget <file>。
临时禁用 rerere: git -c rerere.enabled=false cherry-pick <commit>
查看与排查修改内容
查看已暂存(Staged)内容
查看暂存区修改:git diff --cached 或:git diff --staged
查看已暂存文件: git diff --cached --name-only
查看修改统计:git diff --cached --stat
排查 Cherry-pick 状态异常
查看当前状态: git status
查看是否存在 Cherry-pick 状态文件:ls .git | grep CHERRY_PICK
查看未解决冲突:git ls-files -u
查看操作历史:git reflog -20
查看代码删除历史
查找某段代码被删除的提交:git log -p -S "关键字符串" -- 文件名
使用正则匹配:git log -p -G "关键字符串" -- 文件名
查看当前行最后修改者:git blame -L 100,100 文件名
查看函数完整演变历史:git log -L '/函数名/',/^}/:文件名
拆分 Squash 后的大提交
撤销提交并保留修改
如果已经将多个模块压缩为一个提交:git reset --mixed HEAD~1 或:git reset HEAD~1
效果:
撤销提交
保留所有修改
恢复到工作区
按模块重新提交
提交模块 A:
git add moduleA/
git commit -s -m "moduleA"
提交模块 B:
git add moduleB/
git commit -s -m "moduleB"
提交模块 C:
git add moduleC/
git commit -s -m "moduleC"
恢复指定文件或目录
从上一个提交恢复
恢复目录:git restore --source=HEAD^ -- packages/private/client-mgmt/
旧版写法:git checkout HEAD^ -- packages/private/client-mgmt/
从指定提交恢复
恢复某个目录:git restore --source <commit-id> -- packages/private/client-mgmt/
恢复某个文件:git restore --source <commit-id> -- file.c
提交签名管理
Signed-off-by 与 GPG 签名区别
添加 Signed-off-by:git commit -s
生成:
Signed-off-by: User Name <user@example.com>
添加 GPG/SSH 签名:git commit -S
查看签名:git log --show-signature
批量补充 Signed-off-by
最近 5 个提交补充签名:git rebase -i --exec "git commit --amend --no-edit -s" HEAD~5
当前分支所有新增提交补签:git rebase -i --exec "git commit --amend --no-edit -s" origin/develop/master
同时补充 Signed-off-by 与 GPG 签名
执行:
git rebase -i --exec "git commit --amend --no-edit -s -S" HEAD~5
验证 Signed-off-by:
git log --format=full
验证 GPG:
git log --show-signature
简洁查看:
git log --pretty="%h %G? %s"
其中:
G = 有效签名
N = 无签名
B = 签名无效
- 原文作者:生如夏花
- 原文链接:https://DBL2017.github.io/post/%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8/git-cherry-pick%E5%86%B2%E7%AA%81%E5%A4%84%E7%90%86%E6%8B%86%E5%88%86%E6%8F%90%E4%BA%A4%E4%B8%8E%E7%AD%BE%E5%90%8D%E5%AE%9E%E8%B7%B5%E6%80%BB%E7%BB%93/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。