fix(git): surface non-git-repo as a typed error and align all panels via workspace state
Consolidate `.git` presence detection into a shared `git_repo` module used by both the workspace state watcher and the command preflight helper, replacing duplicated local definitions. Introduce `AppErrorCode::NotAGitRepository` (HTTP 422) and preflight eleven frontend-callable git commands (log, status, list-branches, diff, diff-with-branch, show-diff, show-file, push-info, list-remotes, list-all-branches, commit-branches) so non-git folders short-circuit with a structured error instead of leaking locale-dependent git stderr. Frontend `isNotAGitRepoError` checks the error code first and falls back to a multi-language regex list centralized in `src/i18n/git-error-patterns.ts`, covering the nine languages git actually translates into. Wire the git log panel to `workspaceState.isGitRepo` rather than a local cached flag, so running `git init` or deleting `.git` externally propagates through the watcher and refreshes the panel automatically.
This commit is contained in:
40
src-tauri/src/git_repo.rs
Normal file
40
src-tauri/src/git_repo.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
//! Single source of truth for "is this path a git repository?" detection.
|
||||
//!
|
||||
//! The check is deliberately strict: the exact path must contain a `.git`
|
||||
//! entry (directory for regular repos, file for linked worktrees and
|
||||
//! submodules). We do **not** walk up to ancestors.
|
||||
//!
|
||||
//! Rationale: codeg scopes every workspace-facing feature (file tree
|
||||
//! watcher, git changes panel, log panel) to the directory the user opens.
|
||||
//! If one code path walks up and another doesn't, the UI falls into a
|
||||
//! "schizophrenic" state where some panels see a repo and others don't.
|
||||
//! Keeping the primitive strict forces every consumer onto the same
|
||||
//! interpretation.
|
||||
//!
|
||||
//! Bare repositories are intentionally not supported — they have no working
|
||||
//! tree, which makes them an unusual target for a workspace-oriented editor.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use crate::app_error::AppCommandError;
|
||||
|
||||
/// Returns true when `path` is the root of a git working tree.
|
||||
///
|
||||
/// `.git` may be a directory (normal repo) or a file (worktree/submodule
|
||||
/// pointer). `Path::exists` treats both as present.
|
||||
pub fn is_git_repo(path: &Path) -> bool {
|
||||
path.join(".git").exists()
|
||||
}
|
||||
|
||||
/// Preflight guard for git commands. Short-circuits with a typed error code
|
||||
/// when the target path is not a git working tree, so callers avoid locale-
|
||||
/// dependent stderr parsing for the most common "wrong folder" failure.
|
||||
pub fn ensure_git_repo(path: &str) -> Result<(), AppCommandError> {
|
||||
if is_git_repo(Path::new(path)) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(AppCommandError::not_a_git_repository(format!(
|
||||
"Not a Git repository: {path}"
|
||||
)))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user