{"record":{"id":"8a2a99927f2ea7d8","repo":"gitbutlerapp/gitbutler","slug":"bare-repositories-are-not-supported-8a2a99","errorCode":null,"errorMessage":"bare repositories are not supported","messagePattern":"bare repositories are not supported","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/gitbutler-project/src/project.rs","lineNumber":324,"sourceCode":"    /// Panics if it was not.\n    pub fn unwrap_project(self) -> Project {\n        match self {\n            AddProjectOutcome::Added(p) => p,\n            _ => panic!(\"called `AddProjectOutcome::unwrap_project()` on a non-project outcome\"),\n        }\n    }\n\n    /// Try to get the `Project`, returning an error if it was not added.\n    pub fn try_project(self) -> anyhow::Result<Project> {\n        match self {\n            AddProjectOutcome::Added(p) => Ok(p),\n            AddProjectOutcome::AlreadyExists(_) => Err(anyhow::anyhow!(\"project already exists\")),\n            AddProjectOutcome::PathNotFound => Err(anyhow::anyhow!(\"project path not found\")),\n            AddProjectOutcome::NotADirectory => {\n                Err(anyhow::anyhow!(\"project path is not a directory\"))\n            }\n            AddProjectOutcome::BareRepository => {\n                Err(anyhow::anyhow!(\"bare repositories are not supported\"))\n            }\n            AddProjectOutcome::NonMainWorktree => {\n                Err(anyhow::anyhow!(\"non-main worktrees are not supported\"))\n            }\n            AddProjectOutcome::NoWorkdir => Err(anyhow::anyhow!(\"no workdir found for repository\")),\n            AddProjectOutcome::NoDotGitDirectory => {\n                Err(anyhow::anyhow!(\"no .git directory found in repository\"))\n            }\n            AddProjectOutcome::ReftableRefFormatUnsupported => Err(anyhow::anyhow!(\n                \"unsupported repository reference format: reftable\"\n            )),\n            AddProjectOutcome::NotAGitRepository(msg) => {\n                Err(anyhow::anyhow!(\"not a git repository: {msg}\"))\n            }\n        }\n    }\n}\n","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/gitbutler-project/src/project.rs#L306-L342","documentation":"AddProjectOutcome::BareRepository mapped through try_project: the path hosts a bare repository (no working tree). GitButler's virtual branches operate on a worktree, so bare repos (typically created with git clone --bare / git init --bare) are rejected at add time.","triggerScenarios":"add_project on a directory created with `git init --bare` or `git clone --bare`; a repo whose config has core.bare=true; server-style hosting dirs (git daemon, custom Git servers).","commonSituations":"Trying to onboard a bare mirror used for internal hosting; confusing the bare repo dir with its non-bare clone; tooling that defaults to bare clones for mirrors.","solutions":["Add a non-bare clone/worktree instead: `git clone <bare-repo> <worktree>` and add that directory","Verify before adding: check for core.bare=true in the repo config or the absence of a work tree","If the bare repo is only a mirror, create a working clone elsewhere for daily use"],"exampleFix":"// before\nlet project = add_project(&path, ...).try_project()?; // bare repo -> rejected\n\n// after: pre-detect bare repos and guide the user\nfn is_bare(path: &Path) -> bool {\n    std::process::Command::new(\"git\")\n        .args([\"-C\", path.to_str().unwrap(), \"rev-parse\", \"--is-bare-repository\"])\n        .output().map(|o| o.stdout.trim() == b\"true\").unwrap_or(false)\n}\nif is_bare(&path) {\n    anyhow::bail!(\"bare repositories are unsupported — clone it first: git clone {path:?} worktree\");\n}","handlingStrategy":"validation","validationCode":"fn is_bare_repo(path: &Path) -> bool {\n    std::process::Command::new(\"git\")\n        .args([\"-C\", &path.to_string_lossy(), \"rev-parse\", \"--is-bare-repository\"])\n        .output()\n        .map(|o| o.stdout.trim() == b\"true\")\n        .unwrap_or(false)\n}\nif is_bare_repo(&path) {\n    anyhow::bail!(\"bare repository — clone it to a worktree first\");\n}","typeGuard":null,"tryCatchPattern":"match add_project(&path, ...) {\n    AddProjectOutcome::BareRepository => guide_user_to_clone_worktree(&path),\n    outcome => outcome.try_project(),\n}","preventionTips":["Screen candidate paths with `git rev-parse --is-bare-repository` before onboarding","Only onboard standard clones (folder containing .git), never mirror/bare directories","In pickers, show a clear message when a bare repo is selected so users know to clone instead"],"tags":["gitbutler","project","git","bare-repository","validation"],"backgroundTag":"bare-repository-rejected","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-23T16:17:53.355Z"}