gitbutlerapp/gitbutler · error

Bare repositories are not supported.

Error message

Bare repositories are not supported.

What it means

After successful repo discovery, init_ctx requires a worktree: `repo.workdir()` must return Some. Bare repositories (git init --bare) have no working directory, so GitButler has no files to manage and initialization stops immediately with this message.

Source

Thrown at crates/but/src/setup.rs:125

    let app_settings = crate::app_settings()?;
    // lets try to get the repo from the current directory
    let repo = match gix::discover(&args.current_dir) {
        Ok(repo) => repo,
        Err(_) => anyhow::bail!(
            "No git repository found at {}\nPlease run 'but setup' to initialize the project.",
            &args.current_dir.display()
        ),
    };

    // Check if we're on gitbutler/workspace with non-workspace commits on top
    // before creating the context
    if matches!(options.workspace_check, WorkspaceCheck::Enabled) {
        check_workspace_commits_before_init(&repo, out)?;
    }

    let (ctx, fetch_interval_minutes, last_fetch) = {
        let Some(workdir) = repo.workdir() else {
            anyhow::bail!("Bare repositories are not supported.");
        };
        #[cfg(feature = "legacy")]
        {
            use but_ctx::LegacyProject;

            use crate::command::legacy::setup::check_project_setup;

            if app_settings.feature_flags.single_branch {
                let project = match LegacyProject::find_by_worktree_dir(workdir) {
                    Ok(project) => project,
                    Err(_) => match gitbutler_project::add(workdir)? {
                        gitbutler_project::AddProjectOutcome::Added(project)
                        | gitbutler_project::AddProjectOutcome::AlreadyExists(project) => project,
                        outcome => outcome.try_project()?,
                    },
                };
                let mut ctx =
                    Context::new_from_legacy_project_and_settings(&project, app_settings.clone())?;

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Use a normal (non-bare) clone of the repository
  2. For bare repos, create and cd into a linked worktree: git worktree add ../main
  3. For bare-dotfiles setups, run but from a linked worktree, not the bare directory

Example fix

$ cd ~/repos/dotfiles.git && but branch list   # bare -> fails
$ git -C ~/repos/dotfiles.git worktree add ~/dotfiles-main
$ cd ~/dotfiles-main && but branch list
Defensive patterns

Strategy: validation

Validate before calling

if let Ok(repo) = gix::discover(&cwd) {
    if repo.workdir().is_none() {
        // bare repo: refuse before invoking but, suggest a worktree
    }
}

Prevention

When it happens

Trigger: Running any but command inside a bare repository - `git init --bare`, server-side mirrors, or the popular bare-dotfiles setup (a bare repo whose worktree is $HOME via config).

Common situations: Bare dotfiles repos managed through a shell alias, administering gitolite/forge mirrors, cloning with --bare out of habit.

Related errors


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