遍历 GitCode 的仓库目录树:logs_tree 是分页 dict,gitlink 只在带 path 的子树里露脸
做仓库文档一致性审计,绕不开目录树。GitCode 给的是 GET /api/v2/projects/{路径}/repository/logs_tree?ref=main&per_page=100。照着「返回一个文件列表」的直觉写,第一个版本当场炸:
TypeError: string indices must be integers因为它回的是一个分页字典:
{
"content": [ {name, path, type, commit:{id, message, parent_ids, authored_date, ...}}, ... ],
"page_num": 1,
"page_size": 100,
"total": 7,
"page_count": 1
}条目在 content 下面。这件事还有后半段:total 是真实条数,我第一次扫的时候按单次 100 条写完就开始下结论,直到某个仓的 total 明显大于返回条数才反应过来要翻 page_num。截断是静默的——返回体不会告诉你「后面还有」,只有对 total 与 len(content) 做一次比较才能发现。审计脚本里我因此加了一个硬性动作:分页拉全 + 一旦截断就在结论里标注。
二、path 已经是全路径
content[].path 是相对仓库根的完整路径,例如 converter/assets、config。如果你按「它只给文件名」的假设去手工拼父目录,就会拼出 config/config/roles.json 这种双重前缀,然后拿着这个不存在的路径去断言「README 写的文件不存在」。归一化清单里这是最蠢也最常见的一条。
三、type 有第三种取值,而顶层会把它伪装成 tree
type 除了 tree 和 blob,还有 commit——那正是 git 的 gitlink(submodule 入口)。有意思的是它只在带 path= 的子树查询里才现形:
GET .../logs_tree?ref=main # PPTCraftSkill 顶层 12 条
... web-search type=tree <- 看着像普通目录
GET .../logs_tree?ref=main&path=web-search # total=1
... web-search/AgentWebSearch type=commit <- 其实是 gitlink再补一刀:这个仓根目录的 .gitmodules 用 GET .../repository/files?file_path=.gitmodules 查是 404。有 gitlink 却没有 .gitmodules,clone 出来就是一个空目录。按 README 的说明去跑那个能力的人会直接卡死在这儿。这条是提给仓库的真 Issue 之一,而它的成立完全依赖「查到了子树里的 commit 类型 + 确认 .gitmodules 不存在」这两个证据同时在场。
四、顺手一个字段缺失的坑
组内仓库列表用 GET /api/v2/groups/{org}/projects?page=1&per_page=50,一次能拿全 32 个仓,但返回项里没有 star_count。我照计数排序想挑热门仓,代码跑通了、结果一动不动——字段是 None,排序键全等于 0,静默无操作。要计数只能逐个仓再打一次项目详情接口。
总结这次遍历学到的:接口的返回形状不要靠猜,把顶层字段名打出来看一遍(我每次都把 sorted(j.keys()) 先写进探针输出);分页字段要真的当分页用;子树查询比顶层查询更接近 git 的原始结构。
- 点赞
- 收藏
- 关注作者
评论(0)