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

  1. Remove Depth=1 from FetchOptions (line 1275) if the server mishandles shallow fetch with specific refspecs, or verify the branch exists first via ListReferences.
  2. Before fetching, verify the branch exists remotely: if (repo.Network.ListReferences(repoUrl).All(r => r.CanonicalName != $"refs/heads/{branchName}")) throw a clearer error.
  3. Check repo.Branches using a case-insensitive lookup (repo.Branches.FirstOrDefault(b => string.Equals(b.FriendlyName, $"origin/{branchName}", StringComparison.OrdinalIgnoreCase))).
  4. 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

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


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/798206b1bf815a68. Report an issue: GitHub.