gitbutlerapp/gitbutler · error · anyhow::Error

Repository has no workdir

Error message

Repository has no workdir

What it means

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.

Source

Thrown at crates/but/src/command/legacy/teardown.rs:186

                .paint(format!("Warning: Failed to uninstall Git hooks: {e}"))
        )?;
    }

    // Check out the target branch using Git directly
    if let Some(out) = out.for_human() {
        writeln!(
            out,
            "{}",
            t.hint
                .paint(format!("→ Checking out {target_branch_name}..."))
        )?;
    }

    // Use git checkout via command
    let repo = ctx.repo.get()?;
    let workdir = repo
        .workdir()
        .ok_or_else(|| anyhow::anyhow!("Repository has no workdir"))?;

    let output = std::process::Command::new(gix::path::env::exe_invocation())
        .arg("-C")
        .arg(workdir)
        .arg("checkout")
        .arg(&target_branch_name)
        .output()
        .context("Failed to execute git checkout")?;

    if !output.status.success() {
        // Checkout failed (likely due to local changes), try soft reset instead
        if let Some(out) = out.for_human() {
            writeln!(
                out,
                "  {}",
                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.")
            )?;
        }

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Run `but teardown` from inside the actual working tree of the repository
  2. Verify with `git rev-parse --is-bare-repository` that it prints false in the directory you run from
  3. With bare + linked worktrees, cd into the linked worktree before running but
Defensive patterns

Strategy: validation

Validate before calling

let repo = ctx.repo.get()?;
if repo.workdir().is_none() {
    anyhow::bail!("cannot run teardown in a bare repository; run from a worktree");
}

Prevention

When it happens

Trigger: `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.

Common situations: 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.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/6f8e8c56ae9179c9. Report an issue: GitHub.