如何在Shell脚本中使用git-stash --keep-index规避合并冲突
冲突根因
git stash --keep-index创建的stash条目基于当前HEAD提交的内容生成,stash执行后工作区为比HEAD更新的暂存内容。执行git stash pop时,Git会将基于旧版本HEAD的stash变更合并到新版本的工作区,当两者修改了同一行内容时就会触发合并冲突。
原生Git优化方案
直接绕过git stash的合并逻辑,通过「备份未暂存变更→清理工作区→执行命令→原样恢复」的流程实现需求,全程无合并操作,完全避免冲突,也不需要临时检出完整仓库:
优化后脚本
#!/bin/bash set -euo pipefail # 创建临时目录存储备份内容 tmp_dir=$(mktemp -d) trap 'rm -rf "$tmp_dir"' EXIT # 备份已跟踪文件的未暂存变更(排除Documentation目录) git diff -- . ':!Documentation/' > "$tmp_dir/working.diff" # 备份未跟踪的非忽略文件(排除Documentation目录) git ls-files --others --exclude-standard -- . ':!Documentation/' \ | tar -cf "$tmp_dir/untracked.tar" -T - 2>/dev/null || true # 清理工作区,仅保留暂存区内容 git restore -- . ':!Documentation/' git ls-files --others --exclude-standard -- . ':!Documentation/' \ | xargs -I {} rm -f "{}" 2>/dev/null || true # 执行文档生成 typedoc typedoc_exit_status=$? # 恢复未暂存变更 git apply "$tmp_dir/working.diff" 2>/dev/null || true # 恢复未跟踪文件 [ -s "$tmp_dir/untracked.tar" ] && tar -xf "$tmp_dir/untracked.tar" exit $typedoc_exit_status
方案说明
- 全程使用Git原生能力,无额外依赖
- 无合并逻辑,彻底规避自冲突问题
- 暂存区内容全程不被修改,运行完成后工作区、暂存区状态和执行前完全一致
- 自动兼容带空格/特殊字符的文件名,覆盖边界场景
- 无需额外判断是否存在未暂存变更,空备份的恢复操作无副作用
内容的提问来源于stack exchange,提问作者ELLIOTTCABLE
相关产品推荐
相关产品推荐

