如何获取git cherry推荐提交执行cherry-pick后实际修改的文件
解决方案
核心逻辑是对git cherry输出的每个候选提交做模拟cherry-pick,提取实际产生变更的文件列表,匹配过滤规则即可,不需要手动解析提交原始变更。
具体操作步骤
- 首先确保当前工作区没有未提交的变更,或者提前用
git stash备份本地修改,避免临时操作影响本地内容 - 对每个候选提交(假设提交哈希为
$commit_id)依次执行如下操作:- 执行模拟cherry-pick,仅把变更加载到暂存区,不生成提交也不产生最终提交记录:
git cherry-pick --no-commit --no-ff $commit_id- 提取当前暂存区的变更文件列表,这就是该提交cherry-pick到当前分支后实际会修改的文件:
git diff --cached --name-only- 终止本次cherry-pick,一键恢复工作区和暂存区到操作前的状态:
git cherry-pick --abort - 对比上一步拿到的文件列表,如果所有变更的文件都属于你要过滤的指定文件集合,直接把该提交从候选列表里剔除即可。
可直接使用的脚本示例
假设你要过滤的指定文件是A,git cherry输出的候选提交哈希已经整理到candidates.txt文件中,每行一个哈希值,可以直接用下面的脚本批量过滤:
# 备份当前工作区的未提交修改,避免影响本地内容 git stash push -m "temp stash for cherry filter" # 遍历所有候选提交 while read commit; do # 静默执行模拟cherry-pick git cherry-pick --no-commit --no-ff $commit > /dev/null 2>&1 if [ $? -ne 0 ]; then # 存在冲突的提交可根据自身需求处理,此处默认保留 echo "$commit 存在冲突,保留" git cherry-pick --abort > /dev/null 2>&1 continue fi # 提取实际变更的文件列表 changed_files=$(git diff --cached --name-only) git cherry-pick --abort > /dev/null 2>&1 # 判断是否仅修改了要过滤的指定文件 if [ "$changed_files" = "A" ]; then echo "$commit 仅修改指定文件A,剔除" else echo "$commit 保留" fi done < candidates.txt # 恢复之前备份的本地修改 git stash pop
如果你需要过滤多个指定文件,只需要调整判断逻辑,检查
changed_files中的所有文件是否都属于你的过滤列表即可。
内容的提问来源于stack exchange,提问作者Jochen
相关产品推荐
相关产品推荐

