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()