{"record":{"id":"77ef871129815463","repo":"gitbutlerapp/gitbutler","slug":"cannot-currently-handle-remotes-as-start-position","errorCode":null,"errorMessage":"Cannot currently handle remotes as start position","messagePattern":"Cannot currently handle remotes as start position","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but-graph/src/init/mod.rs","lineNumber":954,"sourceCode":"        };\n        let Options {\n            collect_tags,\n            extra_target_commit_id,\n            commits_limit_hint: limit,\n            commits_limit_recharge_location: mut max_commits_recharge_location,\n            hard_limit,\n            dangerously_skip_postprocessing_for_debugging,\n            worktrees: _,\n        } = options;\n        let max_limit = Limit::new(limit);\n        if ref_name\n            .as_ref()\n            .is_some_and(|name| name.category() == Some(Category::RemoteBranch))\n        {\n            // TODO: see if this is a thing - Git doesn't like to checkout remote tracking branches by name,\n            //       and if we should handle it, we need to setup the initial flags accordingly.\n            //       Also we have to assure not to double-traverse the ref, once as tip and once by discovery.\n            bail!(\"Cannot currently handle remotes as start position\");\n        }\n        let commit_graph = repo.commit_graph_if_enabled()?;\n        let shallow_commits = repo.shallow_commits()?;\n        let mut buf = Vec::new();\n\n        let configured_remote_tracking_branches =\n            remotes::configured_remote_tracking_branches(repo)?;\n        let initial_tips = initial_tips_from_tips(\n            repo,\n            tips,\n            &graph.project_meta,\n            extra_target_commit_id,\n            worktree_tips,\n        )?;\n        graph.traversal_tips = initial_tips.tips.clone();\n        let refs_by_id = repo.collect_ref_mapping_by_prefix(\n            [\n                \"refs/heads/\",","sourceCodeStart":936,"sourceCodeEnd":972,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-graph/src/init/mod.rs#L936-L972","documentation":"Thrown by but-graph's init (crates/but-graph/src/init/mod.rs:954) when the requested start position ref_name is a remote-tracking branch (Category::RemoteBranch, e.g., refs/remotes/origin/main). The code carries an explicit TODO: Git itself refuses to check out remote-tracking branches by name, and the initial traversal flags would need special setup (plus a guard against traversing the ref twice, once as tip and once by discovery). So today this input is rejected up front rather than mis-behaving later.","triggerScenarios":"Building a graph with ref_name = Some(\"refs/remotes/origin/main\") or the shorthand \"origin/main\"; tooling that resolves 'default branch' to the remote-tracking ref instead of a local branch; attempts to start a workspace directly from a fetched remote state.","commonSituations":"Fresh clones where the local branch has not been created yet and only origin/main exists; scripts feeding `git rev-parse --symbolic-full-name` output straight into but-graph; users expecting remote refs to behave like local branches.","solutions":["Pass the local branch name instead (refs/heads/main); create it first if missing: `git branch main origin/main`","Or peel the remote ref to a commit id and use that commit as the start position instead of a ref name","If you actually want a detached start, resolve the remote ref to its OID and pass the commit"],"exampleFix":"// before\nlet graph = but_graph::init(repo, InitOptions { ref_name: Some(\"origin/main\".into()), .. })?; // bails: RemoteBranch\n\n// after\nlet oid = repo.find_reference(\"refs/remotes/origin/main\")?.peel_to_commit()?.id();\nlet graph = but_graph::init(\n    repo,\n    InitOptions {\n        ref_name: Some(\"refs/heads/main\".into()), // local branch\n        extra_target_commit_id: Some(oid),        // remote tip as extra target\n        ..Default::default()\n    },\n)?;","handlingStrategy":"validation","validationCode":"// Reject or rewrite remote-tracking start positions before init\nuse but_graph::Category;\nlet ref_name = match ref_name {\n    Some(name) if name.category() == Some(Category::RemoteBranch) => {\n        // peel to the commit and use it instead of the remote ref\n        let oid = repo.find_reference(name.as_ref())?.peel_to_commit_in_place()?;\n        Some(repo.find_reference(main_branch_name)?.name().to_owned()) // local branch\n            .map(|n| (n, Some(oid)))\n            .map(|(n, o)| { extra_target_commit_id = o; n })\n            .unwrap()\n    }\n    other => other,\n};","typeGuard":"fn is_remote_tracking(name: &gix::refs::FullName) -> bool {\n    name.category() == Some(but_graph::Category::RemoteBranch)\n}","tryCatchPattern":"match but_graph::init(repo, opts) {\n    Ok(g) => g,\n    Err(err) if err.to_string().contains(\"remotes as start position\") => {\n        bail!(\"remote-tracking branches cannot start a graph; pass the local branch or a commit id\")\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Create the local branch after clone (git branch <name> <remote>/<name>) and pass refs/heads/<name>","When automation derives a start ref from git plumbing, filter out refs/remotes/* before feeding but-graph"],"tags":["but-graph","git-refs","remote-branch","initialization","rust"],"backgroundTag":"remote-tracking-branch-unsupported","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}