{"record":{"id":"7dec72dcb3dd2484","repo":"babalae/better-genshin-impact","slug":"release","errorCode":null,"errorMessage":"未找到远程release分支","messagePattern":"未找到远程release分支","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs","lineNumber":908,"sourceCode":"                            {\n                                _logger.LogError(moveEx, \"处理临时文件夹失败，清理临时目录，保留原仓库\");\n                                if (Directory.Exists(tempPath))\n                                    DirectoryHelper.DeleteReadOnlyDirectory(tempPath);\n                                cloneSucceeded = false; // move 失败，视为未更新\n                            }\n                        }\n\n                        updated = cloneSucceeded;\n                        return;\n                    }\n\n                    // 直接获取远程分支的 Commit SHA\n                    var remoteReferences = repo.Network.ListReferences(repoUrl, CreateCredentialsHandler());\n                    var remoteBranch = remoteReferences.FirstOrDefault(r => r.CanonicalName == \"refs/heads/release\");\n\n                    if (remoteBranch == null)\n                    {\n                        throw new Exception(\"未找到远程release分支\");\n                    }\n\n                    var remoteCommitSha = remoteBranch.TargetIdentifier;\n                    var currentCommitSha = repo.Branches[\"release\"]?.Tip?.Sha;\n\n                    // 比较本地和远程commit\n                    if (currentCommitSha == remoteCommitSha)\n                    {\n                        _logger.LogInformation(\"本地仓库已是最新版本，无需更新\");\n                        updated = false;\n                    }\n                    else\n                    {\n                        _logger.LogInformation($\"检测到远程更新: 本地 {currentCommitSha?[..7] ?? \"无\"} -> 远程 {remoteCommitSha[..7]}\");\n                        repo?.Dispose();\n                        repo = null;\n                        CloneRepository(repoUrl, repoPath, \"release\", onCheckoutProgress);\n                        updated = true;","sourceCodeStart":890,"sourceCodeEnd":926,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs#L890-L926","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the configured repoUrl actually has a 'release' branch: run `git ls-remote <repoUrl>` and check for refs/heads/release.","If the upstream renamed the branch, update the hardcoded 'release' branch name in ScriptRepoUpdater.cs:904 (and related CloneRepository calls) to the correct name.","Ensure the credentials handler (CreateCredentialsHandler) returns valid credentials that can see all branches, not a token scoped to a single branch.","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."],"exampleFix":"// before\nvar remoteBranch = remoteReferences.FirstOrDefault(r => r.CanonicalName == \"refs/heads/release\");\nif (remoteBranch == null) throw new Exception(\"未找到远程release分支\");\n\n// after (configurable branch + actionable message)\nvar targetBranch = settings.RepoBranch ?? \"release\";\nvar remoteBranch = remoteReferences.FirstOrDefault(r => r.CanonicalName == $\"refs/heads/{targetBranch}\");\nif (remoteBranch == null)\n    throw new Exception($\"未找到远程 {targetBranch} 分支，请检查仓库地址 {repoUrl} 是否正确（可用 git ls-remote 验证）\");","handlingStrategy":"validation","validationCode":"// Before update, verify the release branch exists on the remote\nvar refs = repo.Network.ListReferences(repoUrl, CreateCredentialsHandler());\nif (refs.All(r => r.CanonicalName == \"refs/heads/release\"))\n    // safe to proceed with release-specific logic\nelse\n    throw new InvalidOperationException(\n        $\"仓库 {repoUrl} 不含 release 分支，请用 git ls-remote 确认\");","typeGuard":null,"tryCatchPattern":"// The outer try at line 930 already catches and re-clones.\n// Improve the message so the toast tells the user the real cause:\ncatch (Exception ex) when (ex.Message.Contains(\"release\"))\n{\n    UIDispatcherHelper.Invoke(() => Toast.Error(\n        $\"仓库地址没有 release 分支：{repoUrl}。请检查配置。\"));\n    throw;\n}","preventionTips":["Make the branch name configurable instead of hardcoding 'release'.","Add a pre-flight `git ls-remote` check before any clone/update.","Validate the configured repoUrl at app startup, not only at update time."],"tags":["git","libgit2sharp","network","branch-config","script-repo"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}