{"record":{"id":"6f8e8c56ae9179c9","repo":"gitbutlerapp/gitbutler","slug":"repository-has-no-workdir","errorCode":null,"errorMessage":"Repository has no workdir","messagePattern":"Repository has no workdir","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but/src/command/legacy/teardown.rs","lineNumber":186,"sourceCode":"                .paint(format!(\"Warning: Failed to uninstall Git hooks: {e}\"))\n        )?;\n    }\n\n    // Check out the target branch using Git directly\n    if let Some(out) = out.for_human() {\n        writeln!(\n            out,\n            \"{}\",\n            t.hint\n                .paint(format!(\"→ Checking out {target_branch_name}...\"))\n        )?;\n    }\n\n    // Use git checkout via command\n    let repo = ctx.repo.get()?;\n    let workdir = repo\n        .workdir()\n        .ok_or_else(|| anyhow::anyhow!(\"Repository has no workdir\"))?;\n\n    let output = std::process::Command::new(gix::path::env::exe_invocation())\n        .arg(\"-C\")\n        .arg(workdir)\n        .arg(\"checkout\")\n        .arg(&target_branch_name)\n        .output()\n        .context(\"Failed to execute git checkout\")?;\n\n    if !output.status.success() {\n        // Checkout failed (likely due to local changes), try soft reset instead\n        if let Some(out) = out.for_human() {\n            writeln!(\n                out,\n                \"  {}\",\n                t.attention.paint(\"⚠ Checkout failed, trying soft reset...\\n  ⚠ This will leave changes from multiple branches in your working directory.\\n  ⚠ You will have to manually remove, stash or re-commit the changes.\")\n            )?;\n        }","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but/src/command/legacy/teardown.rs#L168-L204","documentation":"Teardown shells out to `git checkout -C <workdir>`. It resolves that directory via repo.workdir(), which returns None for bare repositories (including the admin repositories of linked worktrees), so the checkout step cannot run and but fails fast.","triggerScenarios":"`but teardown --checkout-to <branch>` when the resolved gix::Repository is bare: cwd is inside a bare clone or inside .git/worktrees/<name> of a linked worktree.","commonSituations":"Setups with a bare central clone plus linked worktrees where but is run from the wrong side; project discovery landing on the gitdir instead of the worktree.","solutions":["Run `but teardown` from inside the actual working tree of the repository","Verify with `git rev-parse --is-bare-repository` that it prints false in the directory you run from","With bare + linked worktrees, cd into the linked worktree before running but"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let repo = ctx.repo.get()?;\nif repo.workdir().is_none() {\n    anyhow::bail!(\"cannot run teardown in a bare repository; run from a worktree\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check `git rev-parse --is-bare-repository` is false before worktree-mutating commands","Run but from the worktree root, not the gitdir or a bare clone"],"tags":["teardown","bare-repository","workdir","git-checkout"],"backgroundTag":"bare-repository-no-worktree","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}