# 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 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 * `GOSH_CONFIG_PATH`: Override the config directory (Useful for NixOS or testing). * `GOSH_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)