import os
import subprocess

def get_git_objects(repo_path="."):
    """获取 Git 仓库中所有对象的 hash 和大小"""
    pack_dir = os.path.join(repo_path, ".git", "objects", "pack")
    idx_files = [f for f in os.listdir(pack_dir) if f.endswith(".idx")]

    objects = []
    for idx in idx_files:
        idx_path = os.path.join(pack_dir, idx)
        try:
            # 运行 git verify-pack
            result = subprocess.check_output(
                ["git", "verify-pack", "-v", idx_path],
                cwd=repo_path,
                text=True,
                errors="ignore"
            )
            for line in result.splitlines():
                parts = line.split()
                # 只处理包含 "blob" 的行（文件对象）
                if len(parts) >= 5 and parts[1] == "blob":
                    sha = parts[0]
                    size = int(parts[2])  # uncompressed size
                    objects.append((sha, size))
        except subprocess.CalledProcessError as e:
            print(f"Error reading {idx_path}: {e}")
    return objects

def map_objects_to_files(repo_path="."):
    """把对象 hash 映射到文件路径"""
    result = subprocess.check_output(
        ["git", "rev-list", "--objects", "--all"],
        cwd=repo_path,
        text=True,
        errors="ignore"
    )
    mapping = {}
    for line in result.splitlines():
        parts = line.split(" ", 1)
        if len(parts) == 2:
            sha, path = parts
            mapping[sha] = path
    return mapping

def main():
    repo_path = "."  # 当前目录
    objects = get_git_objects(repo_path)
    mapping = map_objects_to_files(repo_path)

    if not objects:
        print("⚠️ 没找到大对象，请确认仓库里有 pack 文件。")
        return

    # 按大小排序，取前 20 个
    objects.sort(key=lambda x: x[1], reverse=True)
    top_n = objects[:20]

    print("Git 仓库里最大的 20 个文件：\n")
    for sha, size in top_n:
        path = mapping.get(sha, "（已删除或不可见文件）")
        print(f"{size/1024:.2f} KB\t{sha}\t{path}")

if __name__ == "__main__":
    main()
