naj/README.md
2026-01-28 23:09:36 +08:00

131 lines
No EOL
4 KiB
Markdown

# Naj
![Naj Banner](assets/naj-banner.jpg)
**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 Cargo
```bash
cargo install naj
```
### From Source
```bash
git clone https://github.com/dotinx/naj.git
cd naj
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)