babalae/better-genshin-impact · error · Exception

未找到远程release分支

Error message

未找到远程release分支

What it means

Thrown by ScriptRepoUpdater when listing remote references of a Git repository (via LibGit2Sharp repo.Network.ListReferences) and no reference matching the canonical name 'refs/heads/release' is found. This means the configured script repo URL does not expose a branch named 'release'. The codebase hardcodes the branch name, so the remote must publish that exact branch.

Source

Thrown at BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs:908

                            {
                                _logger.LogError(moveEx, "处理临时文件夹失败,清理临时目录,保留原仓库");
                                if (Directory.Exists(tempPath))
                                    DirectoryHelper.DeleteReadOnlyDirectory(tempPath);
                                cloneSucceeded = false; // move 失败,视为未更新
                            }
                        }

                        updated = cloneSucceeded;
                        return;
                    }

                    // 直接获取远程分支的 Commit SHA
                    var remoteReferences = repo.Network.ListReferences(repoUrl, CreateCredentialsHandler());
                    var remoteBranch = remoteReferences.FirstOrDefault(r => r.CanonicalName == "refs/heads/release");

                    if (remoteBranch == null)
                    {
                        throw new Exception("未找到远程release分支");
                    }

                    var remoteCommitSha = remoteBranch.TargetIdentifier;
                    var currentCommitSha = repo.Branches["release"]?.Tip?.Sha;

                    // 比较本地和远程commit
                    if (currentCommitSha == remoteCommitSha)
                    {
                        _logger.LogInformation("本地仓库已是最新版本,无需更新");
                        updated = false;
                    }
                    else
                    {
                        _logger.LogInformation($"检测到远程更新: 本地 {currentCommitSha?[..7] ?? "无"} -> 远程 {remoteCommitSha[..7]}");
                        repo?.Dispose();
                        repo = null;
                        CloneRepository(repoUrl, repoPath, "release", onCheckoutProgress);
                        updated = true;

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Verify the configured repoUrl actually has a 'release' branch: run `git ls-remote <repoUrl>` and check for refs/heads/release.
  2. If the upstream renamed the branch, update the hardcoded 'release' branch name in ScriptRepoUpdater.cs:904 (and related CloneRepository calls) to the correct name.
  3. Ensure the credentials handler (CreateCredentialsHandler) returns valid credentials that can see all branches, not a token scoped to a single branch.
  4. Catch the exception at the caller (line 930 already wraps it) and fall back to CloneRepository with a configurable branch instead of a hardcoded one.

Example fix

// before
var remoteBranch = remoteReferences.FirstOrDefault(r => r.CanonicalName == "refs/heads/release");
if (remoteBranch == null) throw new Exception("未找到远程release分支");

// after (configurable branch + actionable message)
var targetBranch = settings.RepoBranch ?? "release";
var remoteBranch = remoteReferences.FirstOrDefault(r => r.CanonicalName == $"refs/heads/{targetBranch}");
if (remoteBranch == null)
    throw new Exception($"未找到远程 {targetBranch} 分支,请检查仓库地址 {repoUrl} 是否正确(可用 git ls-remote 验证)");
Defensive patterns

Strategy: validation

Validate before calling

// Before update, verify the release branch exists on the remote
var refs = repo.Network.ListReferences(repoUrl, CreateCredentialsHandler());
if (refs.All(r => r.CanonicalName == "refs/heads/release"))
    // safe to proceed with release-specific logic
else
    throw new InvalidOperationException(
        $"仓库 {repoUrl} 不含 release 分支,请用 git ls-remote 确认");

Try / catch

// The outer try at line 930 already catches and re-clones.
// Improve the message so the toast tells the user the real cause:
catch (Exception ex) when (ex.Message.Contains("release"))
{
    UIDispatcherHelper.Invoke(() => Toast.Error(
        $"仓库地址没有 release 分支:{repoUrl}。请检查配置。"));
    throw;
}

Prevention

When it happens

Trigger: Calling repo.Network.ListReferences(repoUrl, credentialsHandler) succeeds but the returned reference set contains no entry whose CanonicalName equals 'refs/heads/release'. Occurs when repoUrl points at a fork that renamed/deleted the release branch, the upstream removed it, or the wrong URL is configured.

Common situations: A user pointed the script repo config at a personal fork missing a 'release' branch; the upstream project renamed 'release' to 'main' or 'stable'; network/proxy interference returned a partial ref list; credentials were valid but only revealed restricted refs.

Related errors


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