naj/README.md
2026-01-28 21:50:08 +08:00

121 lines
No EOL
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Naj (我 `/*ŋˤajʔ/`)
**Naj** is a lightweight, secure, and idempotent wrapper for Git, written in Rust. It solves the chaos of managing multiple Git identities (Work vs. Personal) by strictly isolating configurations and preventing accidental identity leaks.
## 🚀 Features
* **🛡️ Fail-Safe Security**: Uses "Blind Injection" to forcibly wipe global identity keys before applying a profile. If your profile lacks a key, Naj fails securely rather than falling back to your global `~/.gitconfig`.
* **⚡ Ephemeral Execution**: Run commands like `naj work commit` without modifying any files on disk. Perfect for one-off fixes.
* **💾 Persistent Switching**: Permanently bind a repository to an identity using Git's native `[include]` directive.
* **🛠️ Zero Config Setup**: Automatically handles `clone` and `init` setup, applying the correct identity immediately.
* **📂 Portable Profiles**: Profiles are stored in `~/.config/naj/profiles/`, designed to be synced via a private Git repository.
## 📦 Installation
### From Source
```bash
cargo install --path .
```
## 📖 Usage
### 1. Management: Create Identities
Naj manages identities as "Profiles".
```bash
# Syntax: naj -c <Name> <Email> <ProfileID>
naj -c "Alice Work" "alice@company.com" "work"
naj -c "Alice Hobby" "alice@gmail.com" "personal"
# List all profiles
naj -l
# Edit a profile (e.g., to add signingkey or sshCommand)
naj -e work
```
### 2. Workflow A: Setup New Projects (Recommended)
When you clone or init a repository, Naj automatically sets up the local config.
```bash
# Clones the repo and immediately binds it to the "work" profile
naj work clone git@github.com:company/backend.git
# Inside the repo, you can now just use standard git
cd backend
git config user.email # Output: alice@company.com
```
### 3. Workflow B: One-off Commands (Exec Mode)
Run a command with a specific identity *without* modifying the repository config.
```bash
# Temporarily commit as "personal" in a work repo (e.g., fixing a typo)
naj personal commit -m "Fix typo"
# Verification
naj personal config user.email
```
### 4. Workflow C: Switch Identity (Persistent)
Change the identity bound to an existing repository.
```bash
cd my-repo
naj work
# If the repo has "dirty" config (manually set user.name), force overwrite it:
naj work -f
```
## ⚙️ Configuration
Naj follows the XDG Base Directory specification.
* **Config File**: `~/.config/naj/naj.toml`
* **Profiles**: `~/.config/naj/profiles/*.gitconfig`
On the first run, Naj will automatically create these directories and a default configuration file.
### Environment Variables
* `NAJ_CONFIG_PATH`: Override the config directory (Useful for NixOS or testing).
* `NAJ_MOCKING=1`: Dry-run mode. Prints the constructed `git` command to stderr instead of executing it.
## 🔒 Security Design: Blind Injection
In **Exec Mode**, Naj does **not** read your local configuration to decide what to override. Instead, it aggressively injects empty values for sensitive keys before applying your profile.
**Example command generated by Naj:**
```bash
git \
-c user.name="" \ # 1. Wipe potential leaks
-c user.email="" \
-c user.signingkey="" \
-c commit.gpgsign=false \
-c include.path=~/.config/naj/profiles/work.gitconfig \ # 2. Apply Profile
commit ...
```
This ensures that if your "work" profile is missing a GPG key, Git will error out ("Secret key not available") rather than silently using your personal GPG key from `~/.gitconfig`.
## 📦 Build Artifacts
Use a machine running Linux to build artifacts for all targets. [rustup](https://rustup.rs/), [cross](https://github.com/cross-rs/cross), and `podman/docker` are required.
Run [build.sh](./build.sh) to build artifacts for all targets.
## 📄 License
[BSD 2-Clause License](./LICENSE)