{"record":{"id":"6c09e0c7daa0daec","repo":"gitbutlerapp/gitbutler","slug":"no-remote-refspec-maps-to-a-local-branch","errorCode":null,"errorMessage":"No remote refspec maps {} to a local branch","messagePattern":"No remote refspec maps (.+?) to a local branch","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-workspace/src/branch/mod.rs","lineNumber":563,"sourceCode":"    Ok(branch_ref)\n}\n\n/// Setup `local_tracking_ref` to track `remote_tracking_ref`, and prepare a locked configuration\n/// transaction with the branch configuration added.\n/// We also return the commit at which `local_tracking_ref` should be placed, which is assumed to not exist.\npub(crate) fn setup_local_tracking_configuration(\n    repo: &gix::Repository,\n    local_tracking_ref: &gix::refs::FullNameRef,\n    remote_tracking_ref: &gix::refs::FullNameRef,\n) -> anyhow::Result<(gix::config::FileTransaction, gix::ObjectId)> {\n    let remote_tracking_commit_id = repo\n        .find_reference(remote_tracking_ref)?\n        .peel_to_commit()?\n        .id();\n    let Some((upstream_branch, remote)) =\n        repo.upstream_branch_and_remote_for_tracking_branch(remote_tracking_ref)?\n    else {\n        anyhow::bail!(\n            \"No remote refspec maps {} to a local branch\",\n            remote_tracking_ref.as_bstr()\n        );\n    };\n    let remote_name = remote\n        .name()\n        .expect(\"a remote loaded by name is never anonymous\");\n\n    let mut config = repo.config_file_mut(repo.common_dir().join(\"config\"))?;\n    let mut section =\n        config.section_mut_or_create_new(\"branch\", Some(local_tracking_ref.shorten()))?;\n    // Each key only where the user has not set it: neither one nor other keys are a reason to skip.\n    let remote_key = gix::config::tree::Branch::REMOTE.name;\n    if section.value(remote_key).is_none() {\n        section.push(remote_key, Some(remote_name.as_bstr()))?;\n    }\n    let merge_key = gix::config::tree::Branch::MERGE.name;\n    if section.value(merge_key).is_none() {","sourceCodeStart":545,"sourceCodeEnd":581,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-workspace/src/branch/mod.rs#L545-L581","documentation":"setup_local_tracking_configuration maps a remote-tracking branch (e.g. refs/remotes/origin/main) to a local branch via gix's upstream_branch_and_remote_for_tracking_branch. When no remote refspec in the configuration maps that tracking ref back to a local branch, the mapping is impossible and setup fails.","triggerScenarios":"Calling apply or local_tracking_branch with a remote_tracking_ref whose remote has no fetch refspec matching it (e.g. fetch refspec deleted or narrowed), so upstream_branch_and_remote_for_tracking_branch returns None.","commonSituations":"Cloning with a custom/narrowed fetch refspec like `+refs/heads/main:refs/remotes/origin/main` then trying to apply a different remote branch; hand-edited .git/config missing `+refs/heads/*:refs/remotes/origin/*`.","solutions":["Restore a wildcard fetch refspec in the remote config: `git config remote.origin.fetch \"+refs/heads/*:refs/remotes/origin/*\"`","Run `git remote set-url`/`git fetch origin` to re-establish standard tracking configuration","Choose a remote-tracking branch that is covered by the existing refspec"],"exampleFix":"// before (config)\n[remote \"origin\"]\n  fetch = +refs/heads/main:refs/remotes/origin/main\n// after (config)\n[remote \"origin\"]\n  fetch = +refs/heads/*:refs/remotes/origin/*","handlingStrategy":"validation","validationCode":"fn has_matching_refspec(repo: &gix::Repository, tracking: &gix::refs::FullNameRef) -> anyhow::Result<bool> {\n    Ok(repo.upstream_branch_and_remote_for_tracking_branch(tracking)?.is_some())\n}","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"No remote refspec maps\") => {\n        eprintln!(\"fix remote fetch refspec in .git/config, then retry\");\n        std::process::exit(1);\n    }\n    other => other?,\n}","preventionTips":["Keep the wildcard fetch refspec +refs/heads/*:refs/remotes/<remote>/* on every remote","Re-check config after custom clones or refspec narrowing","Run git fetch regularly so tracking refs and refspecs stay consistent"],"tags":["git","refspec","config"],"backgroundTag":"invalid-config-value","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}