babalae/better-genshin-impact · error · Exception
仓库结构错误:未找到 repo/ 子目录
Error message
仓库结构错误:未找到 repo/ 子目录
What it means
Thrown by GetRepoSubdirectoryTree when HEAD's tip commit exists but its root tree has no entry named 'repo', or the entry exists but is not a Tree (e.g., it's a file/symlink). The script repo contract requires all script content to live under a top-level 'repo/' directory.
Source
Thrown at BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs:1373
return Repository.IsValid(repoPath) && !Directory.Exists(Path.Combine(repoPath, "repo"));
}
/// <summary>
/// 获取仓库中 repo/ 子目录的树对象
/// </summary>
private Tree GetRepoSubdirectoryTree(Repository repo)
{
var commit = repo.Head?.Tip;
if (commit == null)
{
throw new Exception("仓库HEAD未指向任何提交");
}
// 脚本内容都在 repo/ 子目录下
var repoEntry = commit.Tree["repo"];
if (repoEntry == null || repoEntry.TargetType != TreeEntryTargetType.Tree)
{
throw new Exception("仓库结构错误:未找到 repo/ 子目录");
}
return (Tree)repoEntry.Target;
}
/// <summary>
/// 从中央仓库读取文件内容
/// </summary>
/// <param name="relPath">相对于仓库根目录的路径</param>
/// <returns>文件内容,如果文件不存在则返回null</returns>
public string? ReadFileFromCenterRepo(string relPath)
{
try
{
var repoPath = CenterRepoPath;
// 判断是否为 Git 仓库
bool isGitRepo = IsGitRepository(repoPath);View on GitHub (pinned to a7cb36712d)
Solutions
- Verify the repository layout: `git ls-tree HEAD <repoUrl>` — confirm a 'repo' directory exists at the root.
- Ensure the correct branch is checked out before calling GetRepoSubdirectoryTree (the repo may have repo/ only on 'release').
- If the upstream layout changed, update the hardcoded 'repo' entry name in GetRepoSubdirectoryTree to the new convention, or search recursively for the manifest.
- Provide a clearer error listing available top-level entries so users/devs can see what the repo actually contains.
Example fix
// before
var repoEntry = commit.Tree["repo"];
if (repoEntry == null || repoEntry.TargetType != TreeEntryTargetType.Tree)
throw new Exception("仓库结构错误:未找到 repo/ 子目录");
// after (diagnostic)
var repoEntry = commit.Tree["repo"];
if (repoEntry == null || repoEntry.TargetType != TreeEntryTargetType.Tree)
{
var available = string.Join(", ", commit.Tree.Select(e => $"{e.Name}({e.TargetType})"));
throw new InvalidOperationException(
$"仓库结构错误:未找到 repo/ 子目录。当前顶层条目: {available}");
} Defensive patterns
Strategy: validation
Validate before calling
var repoEntry = commit.Tree["repo"];
if (repoEntry == null || repoEntry.TargetType != TreeEntryTargetType.Tree)
{
var avail = string.Join(", ", commit.Tree.Select(e => e.Name));
throw new InvalidOperationException(
$"未找到 repo/ 子目录。顶层条目: {avail}");
} Type guard
static bool HasRepoSubdir(Repository repo) =>
repo.Head?.Tip?.Tree["repo"] is { TargetType: TreeEntryTargetType.Tree }; Try / catch
catch (Exception ex) when (ex.Message.Contains("repo/"))
{
_logger.LogError("仓库结构不符合预期,请确认仓库约定:{Msg}", ex.Message);
Toast.Error($"仓库结构错误,缺少 repo/ 目录。请重新下载或更换仓库。");
} Prevention
- Document the required 'repo/' layout in the script repo README.
- Validate repo layout right after clone, before any checkout.
- Make the expected subdirectory configurable if upstream may change it.
When it happens
Trigger: commit.Tree["repo"] returns null or returns a TreeEntry whose TargetType != TreeEntryTargetType.Tree. Happens when the cloned repository doesn't follow the expected layout, the 'repo' entry is a file rather than a directory, or the wrong commit/branch was checked out.
Common situations: User configured a non-conforming repository as the script source; upstream restructured and moved scripts out of 'repo/'; a shallow clone with Depth=1 fetched a historical commit before 'repo/' existed; wrong branch checked out (e.g., 'main' has no repo/ but 'release' does).
Related errors
- 仓库HEAD未指向任何提交
- 未找到远程release分支
- 远程仓库中未找到 {branchName} 分支
- 路径中间部分不是目录: {string.Join("/", pathParts.Take(i + 1))}
- 不在主界面,无法识别小地图坐标
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/67cd7dd57105ac4f.
Report an issue: GitHub.