gitbutlerapp/gitbutler · error
not a git repository: {msg}
Error message
not a git repository: {msg} What it means
AddProjectOutcome::NotAGitRepository(msg) mapped through try_project: the path contains something git-like or the discovery failed, and gix returned a specific reason carried in {msg} (e.g. 'not a git repository' style discovery errors). This is the generic fallback when the failure is not one of the precise cases (path missing, not a directory, bare, worktree, no .git, reftable).
Source
Thrown at crates/gitbutler-project/src/project.rs:337
AddProjectOutcome::PathNotFound => Err(anyhow::anyhow!("project path not found")),
AddProjectOutcome::NotADirectory => {
Err(anyhow::anyhow!("project path is not a directory"))
}
AddProjectOutcome::BareRepository => {
Err(anyhow::anyhow!("bare repositories are not supported"))
}
AddProjectOutcome::NonMainWorktree => {
Err(anyhow::anyhow!("non-main worktrees are not supported"))
}
AddProjectOutcome::NoWorkdir => Err(anyhow::anyhow!("no workdir found for repository")),
AddProjectOutcome::NoDotGitDirectory => {
Err(anyhow::anyhow!("no .git directory found in repository"))
}
AddProjectOutcome::ReftableRefFormatUnsupported => Err(anyhow::anyhow!(
"unsupported repository reference format: reftable"
)),
AddProjectOutcome::NotAGitRepository(msg) => {
Err(anyhow::anyhow!("not a git repository: {msg}"))
}
}
}
}
View on GitHub (pinned to caf1f223d3)
Solutions
- Read the embedded {msg} — it carries gix's actual reason for refusing the repository
- Check for newer-git extensions: `git config --list --show-origin | grep -i extension` and disable unsupported ones (e.g. extensions.objectformat)
- Verify with the CLI in the same directory: `git -C <path> status` — if the CLI also fails, fix the repository first
- For sha256 repos, use a standard sha1 clone until the app supports the object format
Example fix
// before
let project = add_project(&path, ...).try_project()?; // 'not a git repository: <msg>'
// after: surface the specific reason to guide the fix
match add_project(&path, ...) {
AddProjectOutcome::NotAGitRepository(msg) => {
return Err(anyhow!("cannot add {path:?}: {msg} — check git extensions and .git integrity"));
}
outcome => outcome.try_project()?,
} Defensive patterns
Strategy: validation
Validate before calling
// cheapest reliable probe: ask git itself if the directory opens as a repo
let probe = std::process::Command::new("git")
.args(["-C", &path.to_string_lossy(), "rev-parse", "--git-dir"])
.output()?;
if !probe.status.success() {
anyhow::bail!("{} is not a usable git repository: {}", path.display(), String::from_utf8_lossy(&probe.stderr));
}
// also screen incompatible extensions (e.g. sha256 object format)
let ext = std::process::Command::new("git")
.args(["-C", &path.to_string_lossy(), "config", "extensions.objectformat"])
.output()?;
if ext.stdout.trim() == b"sha256" {
anyhow::bail!("sha256 object format is not supported — use a sha1 clone");
} Type guard
fn is_openable_git_repo(path: &Path) -> bool {
std::process::Command::new("git")
.args(["-C", &path.to_string_lossy(), "rev-parse", "--git-dir"])
.output()
.map(|o| o.status.success())
.unwrap_or(false)
} Try / catch
match add_project(&path, ...) {
AddProjectOutcome::NotAGitRepository(msg) => {
// msg carries gix's specific reason: show it, suggest fixing extensions/.git
show_actionable_error(&msg)
}
outcome => outcome.try_project(),
} Prevention
- Probe candidate directories with `git rev-parse --git-dir` before onboarding
- Watch for newer-git extensions (objectformat, refstorage) in repo config and reject with guidance
- Never partially copy or sync .git directories — incomplete repos land in this catch-all case
When it happens
Trigger: add_project on a directory where git discovery runs but errors: corrupted .git contents, unreadable config files, invalid repository format version (extensions enabled by a newer git, e.g. objectformat=sha256 in unsupported builds), permission errors reading .git internals.
Common situations: Repos created by much newer git versions with incompatible extensions (sha256 object format, sparse-index-only features); .git partially copied or synced with missing files; OS-level permission problems on .git contents.
Related errors
- bare repositories are not supported
- non-main worktrees are not supported
- no workdir found for repository
- no .git directory found in repository
- unsupported repository reference format: reftable
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/ed05ab654c822b11.
Report an issue: GitHub.