本文目录导读:

- 使用Git内置的合并策略(最简单)
- 自动识别并解决特定文件的冲突
- 通用的自动冲突解决脚本
- 智能冲突解决脚本(准守特定规则)
- 特定场景的自动化脚本示例
- 使用Git hooks自动处理
- 全自动合并脚本
- ⚠️ 重要警告
- 使用建议
用脚本自动解决Git冲突是一个有风险的操作,因为冲突通常需要人工判断上下文,不过在某些特定场景下(比如自动生成的代码、配置文件、或确定性的合并策略),可以通过脚本来自动化处理。
以下提供几种方法,从简单到复杂:
使用Git内置的合并策略(最简单)
#!/bin/bash # 自动使用"ours"或"theirs"策略解决冲突 # 策略1: 总是使用当前分支的版本 git merge --strategy-option ours branch-name # 策略2: 总是使用被合并分支的版本 git merge --strategy-option theirs branch-name # 策略3: 如果在rebase中 git rebase -X theirs branch-name
自动识别并解决特定文件的冲突
#!/bin/bash # 只对特定模式的文件自动解决冲突 # 对package-lock.json使用theirs策略 git checkout --theirs package-lock.json git add package-lock.json # 对配置文件使用ours策略 git checkout --ours config.yml git add config.yml
通用的自动冲突解决脚本
#!/bin/bash
# auto_resolve_conflict.sh
echo "开始处理Git冲突..."
# 获取所有冲突文件
conflict_files=$(git diff --name-only --diff-filter=U)
if [ -z "$conflict_files" ]; then
echo "没有发现冲突文件"
exit 0
fi
for file in $conflict_files; do
echo "处理: $file"
# 方案A: 使用theirs版本(接受来自他们的更改)
git checkout --theirs "$file"
# 或者方案B: 使用ours版本(保留自己的更改)
# git checkout --ours "$file"
# 或者方案C: 使用合并工具自动合并
# git mergetool --tool=vimdiff "$file"
git add "$file"
done
echo "冲突解决完成"
git commit -m "自动解决冲突"
智能冲突解决脚本(准守特定规则)
#!/usr/bin/env python3
"""
智能冲突解析器 - 根据文件类型和冲突内容自动解决
"""
import subprocess
import re
import os
def get_conflict_files():
"""获取冲突文件列表"""
result = subprocess.run(
['git', 'diff', '--name-only', '--diff-filter=U'],
capture_output=True, text=True
)
return result.stdout.strip().split('\n') if result.stdout.strip() else []
def resolve_file(file_path):
"""根据文件类型采取不同策略"""
ext = os.path.splitext(file_path)[1].lower()
# 对于自动生成的文件,使用theirs
if file_path in ['package-lock.json', 'yarn.lock', 'Gemfile.lock']:
print(f" → 自动生成文件,接受theirs: {file_path}")
subprocess.run(['git', 'checkout', '--theirs', file_path])
return True
# 对于代码文件,尝试保留双方更改
if ext in ['.py', '.js', '.java', '.go']:
print(f" → 代码文件,尝试自动合并: {file_path}")
return smart_merge_code(file_path)
# 对于配置文件,使用ours
if file_path in ['config.yml', '.env', 'docker-compose.yml']:
print(f" → 配置文件,保留ours: {file_path}")
subprocess.run(['git', 'checkout', '--ours', file_path])
return True
return False
def smart_merge_code(file_path):
"""尝试智能合并代码文件"""
try:
with open(file_path, 'r') as f:
content = f.read()
# 解析冲突标记
conflict_pattern = r'<<<<<<< HEAD\n(.*?)\n=======\n(.*?)\n>>>>>>> [^\n]+'
conflicts = re.findall(conflict_pattern, content, re.DOTALL)
if not conflicts:
return False
new_content = content
for ours, theirs in conflicts:
# 简单策略:如果变更很小则使用theirs
if len(ours.split('\n')) <= 3 and len(theirs.split('\n')) <= 3:
new_content = new_content.replace(
f'<<<<<<< HEAD\n{ours}\n=======\n{theirs}\n>>>>>>>',
theirs.strip()
)
else:
# 复杂变更,标记为手动处理
print(f" ⚠️ {file_path} 包含复杂冲突,需要手动处理")
return False
# 检查是否还有未解决的冲突
if re.search(r'<<<<<<<|=======|>>>>>>>', new_content):
print(f" ⚠️ {file_path} 仍有未处理冲突")
return False
with open(file_path, 'w') as f:
f.write(new_content)
return True
except Exception as e:
print(f" ❌ 处理 {file_path} 时出错: {e}")
return False
def main():
"""主函数"""
print("🔍 扫描冲突文件...")
conflict_files = get_conflict_files()
if not conflict_files:
print("✅ 没有冲突文件")
return
print(f"发现 {len(conflict_files)} 个冲突文件")
resolved = 0
failed = []
for file_path in conflict_files:
if file_path: # 确保文件路径不为空
if resolve_file(file_path):
subprocess.run(['git', 'add', file_path])
resolved += 1
else:
failed.append(file_path)
print(f"\n📊 统计:")
print(f" - 自动解决: {resolved}")
print(f" - 需要手动处理: {len(failed)}")
if failed:
print("\n⚠️ 以下文件需要手动处理:")
for f in failed:
print(f" - {f}")
if resolved > 0:
print("\n💡 运行 git commit 来完成合并")
if __name__ == "__main__":
main()
特定场景的自动化脚本示例
1 自动解决package.json冲突
#!/bin/bash
# 针对package.json的智能合并
# 保留两个版本的依赖
resolve_package_json() {
local file="package.json"
if [ ! -f "$file" ]; then
return
fi
# 使用git的合并策略
git checkout --theirs "$file"
git add "$file"
}
# 在合并后运行
resolve_package_json
2 CI/CD环境中的自动冲突处理
# .gitlab-ci.yml 或 GitHub Actions
stages:
- merge
auto_merge:
stage: merge
script:
- git config user.email "bot@example.com"
- git config user.name "Auto Merge Bot"
- git checkout main
- git merge --no-edit develop || true
- |
# 自动解决已知类型的冲突
for file in $(git diff --name-only --diff-filter=U); do
case "$file" in
*.lock | package-lock.json | yarn.lock)
git checkout --theirs "$file"
git add "$file"
;;
*.md | *.txt)
git checkout --ours "$file"
git add "$file"
;;
*)
echo "需要手动处理: $file"
;;
esac
done
- git commit -m "自动合并开发分支" || true
- git push
使用Git hooks自动处理
#!/bin/bash
# post-merge hook - 自动解决特定文件的冲突
echo "检查合并后的冲突..."
if [ -f "package-lock.json" ]; then
echo "自动更新package-lock.json"
npm install 2>/dev/null || true
fi
# 检查是否有未解决的冲突
if git diff --check 2>/dev/null | grep -q "conflict"; then
echo "⚠️ 仍有未解决的冲突"
fi
全自动合并脚本
#!/bin/bash
# git_auto_merge.sh - 完全自动化合并
set -e
# 配置
SOURCE_BRANCH=${1:-"develop"}
TARGET_BRANCH=${2:-"main"}
AUTO_RESOLVE_FILES=(
"package-lock.json"
"yarn.lock"
"pnpm-lock.yaml"
".gitignore"
)
echo "🔄 自动合并 $SOURCE_BRANCH → $TARGET_BRANCH"
# 切换到目标分支并拉取最新代码
git checkout "$TARGET_BRANCH"
git pull origin "$TARGET_BRANCH"
# 合并源分支
echo "📥 合并 $SOURCE_BRANCH..."
git merge "$SOURCE_BRANCH" --no-edit || true
# 自动解决特定文件的冲突
echo "🔧 自动解决已知冲突文件..."
for file in "${AUTO_RESOLVE_FILES[@]}"; do
if [ -f "$file" ]; then
echo " → 解决: $file"
git checkout --theirs "$file" 2>/dev/null || git checkout --ours "$file" 2>/dev/null || true
git add "$file" 2>/dev/null || true
fi
done
# 提交合并
if git diff --cached --quiet; then
echo "✅ 没有需要提交的更改"
else
git commit -m "chore: 自动合并 $SOURCE_BRANCH 到 $TARGET_BRANCH"
echo "✅ 合并完成"
fi
⚠️ 重要警告
- 自动解决冲突有风险:可能会引入错误或丢失重要更改
- 只适用于特定场景:
- 自动生成的文件(锁文件、编译产物)
- 配置文件(格式化或注释差异)
- 确定性的代码变更
- 建议的实践:
- 先在小范围测试
- 保留备份或使用reflog
- 添加详细的日志记录
- 对关键文件不自动处理
使用建议
- 始终先检查哪些文件有冲突
- 对不同类型的文件采用不同的策略
- 添加日志和回滚机制
- 在CI/CD中使用时,对于无法自动解决的情况要报警
自动化是工具,不是替代品,对于复杂的业务逻辑冲突,人工检查永远是必要的。