git比较不同分支的不同提交文件差异

时间:2025-04-22 20:20:17

背景:只想比较某2个分支的某2次提交的差异,不需要带上父提交。

以commitA为基准,用commitB去比较差异

直接上代码:


commitA=xxxx1
commitB=xxxx2
outputFile="output.txt"

# 获取与第一个父提交的文件列表
filesA=$(git diff --name-only $commitA^1 $commitA)
filesB=$(git diff-tree --no-commit-id --name-only -r $commitB)

# 创建关联数组来存储文件状态
declare -A fileStatus

# 将 filesA 和 filesB 的文件状态存入关联数组
for file in $filesA; do
    fileStatus["$file"]="DELETE"
done

for file in $filesB; do
    if [[ -n "${fileStatus["$file"]}" ]]; then
        fileStatus["$file"]="MODIFY"
    else
        fileStatus["$file"]="ADD"
    fi
done

# 输出文件状态
for file in "${!fileStatus[@]}"; do
    echo "$file (${fileStatus[$file]})" >> "$outputFile"
done

可以用python实现美化树结构

def build_tree(file_list):
    tree = {}
    for line in file_list:
        # 分割文件路径和状态
        file_path, status = line.rsplit(' ', 1)
        parts = file_path.split('/')

        current = tree
        for part in parts[:-1]:  # 处理目录部分
            if part not in current:
                current[part] = {}
            current = current[part]

        # 处理文件部分
        file_name = parts[-1]
        current[file_name] = status.strip('()')  # 只在文件上存储状态

    return tree

def print_tree(node, prefix='', is_last=True):
    for i, (key, value) in enumerate(node.items()):
        connector = '└── ' if is_last else '├── '
        # 判断是否是文件,最后一个文件不加 '/'
        if isinstance(value, str):  # 如果是文件,直接打印状态
            print(prefix + connector + key + ' (' + value + ')')
        else:  # 如果是目录,打印目录名
            print(prefix + connector + key + '/')

        if isinstance(value, dict):
            new_prefix = prefix + ('    ' if is_last else '│   ')
            print_tree(value, new_prefix, i == len(node) - 1)

# 读取文件内容
with open('output.txt', 'r') as file:
    file_content = file.readlines()
    file_content = [line.strip() for line in file_content]

# 构建树形结构
file_tree = build_tree(file_content)

# 打印树形结构
print("文件树形结构:")
print_tree(file_tree)