luff 0.2.1

Print files with formatting
Documentation
# Git Module

**Purpose**: Git CLI integration for repository root discovery.

## File Responsibilities

### repository.rs

- **find_repository_root()**: Convenience wrapper using `current_dir()`
- **find_repository_root_from(start_dir)**: Core logic, executes `git rev-parse --show-toplevel`
- **Error handling**: Git not installed, not in repo, invalid output, non-absolute path
- **Path conversion**: stdout bytes → UTF-8 string → trimmed → PathBuf

### mod.rs

- **Re-exports**: Makes `find_repository_root()` and `find_repository_root_from()` public

## Critical Functions

```rust
find_repository_root() -> Result<PathBuf>
    // Uses current_dir(), delegates to find_repository_root_from()

find_repository_root_from(start_dir: &Path) -> Result<PathBuf>
    // Shells out: git rev-parse --show-toplevel
    // Returns: Absolute path to repo root
```

## Git Command Execution

```
Command::new("git")
    .args(["rev-parse", "--show-toplevel"])
    .current_dir(start_dir)  // caller-supplied directory
    .output()
Check output.status.success()
Parse output.stdout as UTF-8
Trim whitespace
Verify path is absolute (runtime check)
Convert to PathBuf
```

## Error Cases

| Condition              | Error Variant          | Context                                          |
| ---------------------- | ---------------------- | ------------------------------------------------ |
| cwd inaccessible       | `GitCommandFailed`     | command, stderr, io source, suggestion            |
| Git not in PATH        | `GitCommandFailed`     | Detects `ErrorKind::NotFound`, suggests install   |
| Git exec fails (other) | `GitCommandFailed`     | Includes start_dir in command string              |
| Not in git repo        | `NotInGitRepository`   | Includes start_dir and git's stderr output        |
| Invalid UTF-8 output   | `GitInvalidUtf8`       | Wraps `FromUtf8Error` source                      |
| Non-absolute path      | `GitCommandFailed`     | `InvalidData` io error, defensive check           |

All variants carry a `suggestion` field consumed by `miette` diagnostics.

## Key Invariants

- Only shells out to git CLI (no libgit2 dependency)
- Returns absolute path to repository root (runtime-verified)
- Does not verify .git directory exists
- Does not read .git/config or other git internals
- Single invocation per CLI run (not cached)

## API Design

- `find_repository_root_from(&Path)` is the core function accepting any starting directory
- `find_repository_root()` is a convenience wrapper using `current_dir()`
- Separation enables testability, composability, and use from non-cwd contexts

## Performance Notes

- Single subprocess spawn (~1-2ms typical)
- Not cached (`Config::from_args()` calls once)
- Fast enough for CLI startup (no optimization needed)

## Security Considerations

- Uses `Command` with explicit args (no shell, no injection risk)
- Trusts git binary in system PATH
- Output sanitized via UTF-8 conversion + trim
- No arbitrary command execution

## Extension Points

- Caching: Wrap in `std::sync::OnceLock` for repeated calls
- libgit2 alternative: Replace with `git2` crate for pure-Rust impl
- Config reading: Add functions for `.gitconfig` parsing
- Branch/status: Add `current_branch()`, `is_dirty()` using same pattern