67 lines
2.1 KiB
Python
67 lines
2.1 KiB
Python
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()
|