{"record":{"id":"ec544f17a5f7f468","repo":"gitbutlerapp/gitbutler","slug":"branch-branch-name-not-found","errorCode":null,"errorMessage":"Branch {branch_name} not found","messagePattern":"Branch (.+?) not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-api/src/land/merge.rs","lineNumber":39,"sourceCode":"    Merge {\n        oid: gix::ObjectId,\n        target_oid: gix::ObjectId,\n    },\n}\n\n/// Decide how to land `branch_name` onto the target and, for the merge case, build a signed,\n/// rename-aware merge commit. Conflicts bail here, before anything is pushed or moved.\npub(super) fn decide_land_outcome(\n    repo: &gix::Repository,\n    branch_name: &str,\n    fetch_remote_name: &str,\n    target_branch_name: &str,\n    no_ff: bool,\n) -> anyhow::Result<LandOutcome> {\n    let feature_ref_name = format!(\"refs/heads/{branch_name}\");\n    let feature_oid = repo\n        .try_find_reference(&feature_ref_name)?\n        .ok_or_else(|| anyhow::anyhow!(\"Branch {branch_name} not found\"))?\n        .into_fully_peeled_id()?\n        .detach();\n\n    let target_ref_name = format!(\"refs/remotes/{fetch_remote_name}/{target_branch_name}\");\n    let target_oid = repo\n        .try_find_reference(&target_ref_name)?\n        .ok_or_else(|| anyhow::anyhow!(\"Target branch {target_ref_name} not found\"))?\n        .into_fully_peeled_id()?\n        .detach();\n\n    // No common ancestor: refuse rather than merge two unrelated histories onto the target.\n    let Some(merge_base) = super::merge_base_opt(repo, feature_oid, target_oid)? else {\n        bail!(\n            \"Cannot land {branch_name}: it shares no history with {fetch_remote_name}/{target_branch_name}\"\n        );\n    };\n\n    if merge_base == feature_oid {","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/2497b8007aa4a1922dae9a805b32ffe5b5037785/crates/but-api/src/land/merge.rs#L21-L57","documentation":"branch_land resolves refs/heads/<branch_name> in the local repository via gix try_find_reference; if no such local branch exists it bails with this message before fetching or mutating anything. It looks for a real local ref — remote-only names, virtual names, and typos all fail here.","triggerScenarios":"`but land <name>` (branch_land -> decide_land_outcome) where refs/heads/<name> does not exist: typo, name written as origin/<name>, branch that exists only on the remote, or a local branch deleted/pruned earlier.","commonSituations":"Tab-completing remote branch names; landing after branch cleanup pruned the local ref; case-sensitivity mistakes; scripts forwarding reflogs or remote names.","solutions":["List candidates first: git branch --list (or the workspace stack listing) and land the exact local branch name.","If the branch exists only on the remote, materialize the local ref first: git fetch <remote> && git branch <name> <remote>/<name>.","Strip remote prefixes — pass the short name, not origin/<name>."],"exampleFix":"git branch --list 'feat/*'\ngit branch feat/auth origin/feat/auth   # only if the local ref is missing\nbut land feat/auth","handlingStrategy":"validation","validationCode":"fn local_branch_exists(repo: &gix::Repository, branch: &str) -> anyhow::Result<bool> {\n    Ok(repo.try_find_reference(&format!(\"refs/heads/{branch}\"))?.is_some())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Resolve names with git rev-parse --verify refs/heads/<name> (or try_find_reference) before land.","Offer only local stack branch names in UI pickers.","Strip remote prefixes from user-supplied names."],"tags":["land","branch-not-found","git-refs","api"],"backgroundTag":"branch-not-found","analyzedSha":"2497b8007aa4a1922dae9a805b32ffe5b5037785","analyzedAt":"2026-08-17T00:30:25.648Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}