babalae/better-genshin-impact · error · Exception
远程仓库中未找到 {branchName} 分支
Error message
远程仓库中未找到 {branchName} 分支 What it means
Thrown during initial repository clone/fetch (CloneRepository flow) when Commands.Fetch with a refspec for the requested branch completes but repo.Branches["origin/{branchName}"] returns null. LibGit2Sharp created the remote-tracking ref under a different name, the fetch silently failed to populate the branch, or the branch name contains unexpected characters.
Source
Thrown at BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs:1289
var fetchOptions = new FetchOptions
{
TagFetchMode = TagFetchMode.None,
ProxyOptions = { ProxyType = ProxyType.None },
Depth = 1, // 浅拉取,只获取最新的提交
CredentialsProvider = CreateCredentialsHandler(), // 添加凭据处理器
OnTransferProgress = progress =>
{
onCheckoutProgress?.Invoke($"拉取对象 {progress.ReceivedObjects}/{progress.TotalObjects}", progress.ReceivedObjects, progress.TotalObjects);
return true;
}
};
string refSpec = $"+refs/heads/{branchName}:refs/remotes/origin/{branchName}";
Commands.Fetch(repo, remote.Name, new[] { refSpec }, fetchOptions, "初始化拉取");
// 获取远程分支
var remoteBranch = repo.Branches[$"origin/{branchName}"];
if (remoteBranch == null)
throw new Exception($"远程仓库中未找到 {branchName} 分支");
// 创建本地分支
var localBranch = repo.CreateBranch(branchName, remoteBranch.Tip);
repo.Branches.Update(localBranch, b => b.TrackedBranch = remoteBranch.CanonicalName);
// 手动检出HEAD到新分支
repo.Refs.UpdateTarget(repo.Refs.Head, localBranch.CanonicalName);
// 手动检出 repo.json 文件
CheckoutRepoJson(repo, remoteBranch.Tip);
}
finally
{
repo?.Dispose();
}
}
/// <summary>View on GitHub (pinned to a7cb36712d)
Solutions
- Remove Depth=1 from FetchOptions (line 1275) if the server mishandles shallow fetch with specific refspecs, or verify the branch exists first via ListReferences.
- Before fetching, verify the branch exists remotely: if (repo.Network.ListReferences(repoUrl).All(r => r.CanonicalName != $"refs/heads/{branchName}")) throw a clearer error.
- Check repo.Branches using a case-insensitive lookup (repo.Branches.FirstOrDefault(b => string.Equals(b.FriendlyName, $"origin/{branchName}", StringComparison.OrdinalIgnoreCase))).
- Inspect the actual refspecs created after Fetch via repo.Network.Remotes[remote.Name].FetchRefSpec to confirm the refspec matched server-side refs.
Example fix
// before
string refSpec = $"+refs/heads/{branchName}:refs/remotes/origin/{branchName}";
Commands.Fetch(repo, remote.Name, new[] { refSpec }, fetchOptions, "初始化拉取");
var remoteBranch = repo.Branches[$"origin/{branchName}"];
if (remoteBranch == null)
throw new Exception($"远程仓库中未找到 {branchName} 分支");
// after (verify existence first, clearer message)
var refs = repo.Network.ListReferences(repoUrl, CreateCredentialsHandler());
if (refs.All(r => r.CanonicalName != $"refs/heads/{branchName}"))
throw new Exception($"远程仓库 {repoUrl} 不存在分支 {branchName},请检查仓库地址与分支名");
Commands.Fetch(repo, remote.Name, new[] { refSpec }, fetchOptions, "初始化拉取");
var remoteBranch = repo.Branches[$"origin/{branchName}"];
if (remoteBranch == null)
throw new Exception($"拉取完成但未生成 origin/{branchName} 跟踪分支,可能是浅克隆或服务端不支持该 refspec"); Defensive patterns
Strategy: validation
Validate before calling
// Verify remote branch exists before fetch
var remoteRefs = repo.Network.ListReferences(repoUrl, CreateCredentialsHandler());
bool exists = remoteRefs.Any(r => r.CanonicalName == $"refs/heads/{branchName}");
if (!exists)
throw new InvalidOperationException(
$"远程仓库 {repoUrl} 不存在分支 {branchName}"); Try / catch
try { CloneRepository(repoUrl, repoPath, branchName, onCheckoutProgress); }
catch (Exception ex) when (ex.Message.Contains("未找到") || ex.Message.Contains("分支"))
{
_logger.LogError(ex, "克隆失败:分支 {Branch} 不存在于 {Url}", branchName, repoUrl);
// surface to UI, do not retry blindly
throw;
} Prevention
- Avoid Depth=1 shallow fetch when the server's refspec handling is unknown.
- Confirm branch existence via ListReferences before Commands.Fetch.
- Log the refspecs actually applied after Fetch for post-mortem.
When it happens
Trigger: Commands.Fetch(repo, remote.Name, ["+refs/heads/{branchName}:refs/remotes/origin/{branchName}"], fetchOptions, ...) is called, then repo.Branches[$"origin/{branchName}"] is accessed. The indexer returns null when the remote-tracking branch was not created — typically because the upstream branch does not exist, the fetch was a shallow clone (Depth=1) that pruned it, or a transient fetch error was swallowed.
Common situations: Shallow fetch (Depth=1 set on line 1275) combined with a server that doesn't honor the refspec; the requested branch was deleted between a clone attempt and this call; branch name casing mismatch on case-sensitive servers; Gitea/GitHub auth token lacks read scope for that branch.
Related errors
- 未找到远程release分支
- 仓库HEAD未指向任何提交
- 仓库结构错误:未找到 repo/ 子目录
- 路径中间部分不是目录: {string.Join("/", pathParts.Take(i + 1))}
- 仓库URL不能为空
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/798206b1bf815a68.
Report an issue: GitHub.