gitbutlerapp/gitbutler · error · anyhow::Error
No git repository found.
Error message
No git repository found.
What it means
End state of `setup_new_repo`: the current directory is not inside a git repository, so setup offers an interactive prompt ('Would you like to initialize a new one? [y/N]'). The error is returned when the user answers anything other than `y`, or when there is no interactive terminal at all (`prepare_for_terminal_input` yields None), in which case the prompt never appears.
Source
Thrown at crates/but/src/command/legacy/setup.rs:650
"{}",
t.hint
.paint("Initializing new repository and creating an empty first commit...")
)?;
let repo = gix::init(current_dir)?;
create_empty_initial_commit(&repo)?;
writeln!(
&mut progress as &mut dyn FmtWrite,
"{}",
t.success
.paint("Initialized a new repository and created an empty first commit.\n")
)?;
return Ok(repo);
}
}
Err(anyhow::anyhow!("No git repository found."))
}
fn create_empty_initial_commit(repo: &gix::Repository) -> anyhow::Result<()> {
// In an unborn repo, this returns the well-known empty-tree id.
// (It works even if the empty tree object isn’t physically in the ODB.)
let empty_tree = repo.head_tree_id_or_empty().expect("repo access failed"); // -> Id<'_>
let empty_tree = empty_tree.detach(); // -> ObjectId (optional; commit() accepts Into<ObjectId> anyway)
// No parents for the first commit. Update HEAD (writes through to refs/heads/main).
repo.commit(
"HEAD",
"Initial empty commit\n",
empty_tree,
std::iter::empty::<gix::hash::ObjectId>(),
)?;
Ok(())
}View on GitHub (pinned to caf1f223d3)
Solutions
- cd into the actual repository clone (or pass its path) and rerun setup
- If you genuinely want a new repo there, run setup interactively and answer `y`, or just `git init` and make an initial commit yourself first
- In scripts, ensure the clone step succeeded and run `git init` before invoking setup non-interactively
Example fix
# before: ran in the wrong folder, prompt declined / no TTY mkdir -p ~/work && cd ~/work && but setup # after: enter the repo first cd ~/work/project && but setup
Defensive patterns
Strategy: validation
Validate before calling
if gix::discover(std::env::current_dir()?).is_err() {
if !std::io::stdin().is_terminal() {
anyhow::bail!("not inside a git repository and no TTY to prompt; run 'git init' first");
}
// else let setup offer the init prompt
} Try / catch
match run_setup(&mut ctx, &mut out) {
Ok(_) => {}
Err(err) if err.to_string() == "No git repository found." => {
// guidance: cd into the clone, or git init, or answer 'y' when prompted
}
Err(err) => return Err(err),
} Prevention
- cd into the clone (or pass its path) before running setup
- In non-interactive pipelines, run `git init` and an initial commit explicitly beforehand
- Fail the pipeline early if the clone step did not produce a `.git`
When it happens
Trigger: Running `but setup` in a plain directory and declining the init prompt (answering N, n, empty enter, or any non-'y' input); running setup non-interactively (piped stdin, CI) where the prompt cannot be shown at all.
Common situations: Forgot to `cd` into the clone before running the tool; CI or cron pipelines with no TTY; expecting setup to find a repo that was never cloned; a clone step silently failed earlier in the script.
Related errors
- The path {} is not a git repository.
- The repository at {} is bare. GitButler requires a non-bare
- The repository at {} is a non-main worktree. GitButler requi
- The repository at {} has no working directory. GitButler req
- The repository at {} has no .git directory. GitButler requir
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/2e186385e0df6ecd.
Report an issue: GitHub.