git比较不同分支的不同提交文件差异
背景:只想比较某2个分支的某2次提交的差异,不需要带上父提交。
以commitA为基准,用commitB去比较差异
直接上代码:
#!/bin/bashcommitA=d347dad9f25fb17db89eadcec7ea0f1bacbf7d29
commitB=a6cc0c1a863b5c56d5f48bff396e4cd6966e8aaa# 临时文件
a_files=$(mktemp)
b_files=$(mktemp)
common_files=$(mktemp)
deleted_files=$(mktemp)
added_files=$(mktemp)
all_files=$(mktemp)# 获取提交文件
git show --name-only --pretty="" "$commitA" > "$a_files"
git show --name-only --pretty="" "$commitB" > "$b_files"# 判断关系
comm -12 <(sort "$a_files") <(sort "$b_files") > "$common_files"
comm -23 <(sort "$a_files") <(sort "$b_files") > "$deleted_files"
comm -13 <(sort "$a_files") <(sort "$b_files") > "$added_files"# 状态归一化
while read -r file; doif [[ -n "$file" ]]; then# 统计行数变化stats=$(git diff --numstat "$commitA" "$commitB" -- "$file")added=$(echo "$stats" | awk '{print $1}')removed=$(echo "$stats" | awk '{print $2}')echo "MODIFIED $file +$added -$removed" >> "$all_files"fi
done < "$common_files"while read -r file; doif [[ -n "$file" ]]; thenecho "DELETED $file" >> "$all_files"fi
done < "$deleted_files"while read -r file; doif [[ -n "$file" ]]; thenecho "ADDED $file" >> "$all_files"fi
done < "$added_files"echo "📁 文件差异目录树结构(以 $commitA 为基础,对比 $commitB)"
echodeclare -A printed_dirsprint_tree() {local status="$1"local file="$2"local meta="$3"IFS='/' read -ra parts <<< "$file"local indent=""local current_path=""for ((i = 0; i < ${#parts[@]} - 1; i++)); docurrent_path+="${parts[i]}/"indent+="│ "if [[ -z "${printed_dirs[$current_path]}" ]]; thenecho "${indent%│ }├── ${parts[i]}"printed_dirs[$current_path]=1fidonelocal fname="${parts[-1]}"case "$status" inMODIFIED)echo "${indent}├── $fname (MODIFIED $meta)"
# git diff "$commitA" "$commitB" -- "$file";;DELETED)echo "${indent}├── $fname (DELETED)";;ADDED)echo "${indent}├── $fname (ADDED)"
# git diff "$commitA" "$commitB" -- "$file";;esac
}# 输出树
while read -r line; dostatus=$(echo "$line" | awk '{print $1}')file=$(echo "$line" | awk '{print $2}')meta=$(echo "$line" | cut -d' ' -f3-)print_tree "$status" "$file" "$meta"
done < "$all_files"# 清理
rm "$a_files" "$b_files" "$common_files" "$deleted_files" "$added_files" "$all_files"