Skip to content

balaianu/git-persona

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

git-persona

Manage multiple Git identities with SSH keys and includeIf automation — no more accidental commits with the wrong email.

Tests License: MIT Version Bash Buy Me A Coffee


The problem

You have a work GitHub account and a personal GitHub account. You clone repos into different folders. But every now and then, you commit to a personal repo with your work email — or worse, commit to a work repo with your personal email. Now your commit history is wrong, and fixing it means rewriting history.

Managing this manually is error-prone:

git config user.name "Work Name"
git config user.email work@example.com
git config core.sshCommand "ssh -i ~/.ssh/id_ed25519_work"
# ... repeat for every single repo

The solution

git-persona creates identity profiles and wires them up to folders. Any repo under a profile's folder automatically uses the right name, email, and SSH key. No per-repo config needed.

git persona create work "Work Name" work@example.com ~/dev/work
git persona create personal "Personal Name" personal@example.com ~/dev/personal

Now every repo under ~/dev/work/ uses your work identity. Every repo under ~/dev/personal/ uses your personal identity. Done.

Features

  • Automatic identity switching — repos in different folders use different Git identities via includeIf
  • SSH key management — generates ed25519 keys per profile, names them consistently
  • Per-repo override — apply a profile to any repo manually
  • Current profile detection — see which identity is active in any directory
  • Zero dependencies — pure bash, works on any Linux and macOS
  • Git subcommand — use git persona natively (not just git-persona)

Table of contents

Requirements

  • Bash 4.0+
  • Git 2.13+ (for includeIf support)
  • OpenSSH (for ssh-keygen)

Compatibility

Platform Status Notes
Linux (Ubuntu, Debian, Fedora, Arch, etc.) Fully supported
Alpine Linux Fully supported Pure bash, no GNU sed needed
macOS Fully supported Uses built-in bash (or Homebrew bash 5+)
Windows (Git Bash) Untested, expected to work Comes with Git for Windows. See note below
Windows (WSL) Fully supported Same as Linux
Windows (PowerShell/cmd) Not supported Use Git Bash or WSL

Windows with Git Bash: Expected to work but not yet tested. Git for Windows includes a full bash environment with ssh-keygen and all required tools. There may be a path format mismatch between Git Bash's MSYS-style paths (/c/Users/...) and what Git's includeIf expects on Windows. Install via the one-liner from a Git Bash terminal. If you test it, please open an issue with your results.

Installation

One-liner (recommended)

curl -fsSL https://raw.githubusercontent.com/balaianu/git-persona/main/install.sh | bash

Downloads the script and installs it to ~/.local/bin/git-persona. No cloning required.

From source

git clone https://github.com/balaianu/git-persona.git
cd git-persona
make install

This installs git-persona to ~/.local/bin/ by default. Make sure that directory is in your PATH:

echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Custom install location

make install PREFIX=/usr/local

Update

cd git-persona
git pull
make update

Uninstall

cd git-persona
make uninstall

This removes the script from ~/.local/bin/. Profile data in ~/.config/git-persona/ is not removed. To remove all profile data:

rm -rf ~/.config/git-persona

Usage

Since the script is named git-persona, Git automatically recognizes it as a subcommand. Both forms work identically:

git persona create work "Name" work@example.com ~/dev/work   # recommended
git-persona create work "Name" work@example.com ~/dev/work   # also works

Create a profile

git persona create work "Work Name" work@example.com ~/dev/work

This will:

  1. Generate an SSH key at ~/.ssh/id_ed25519_git_work
  2. Create a profile config at ~/.config/git-persona/profiles/work.gitconfig
  3. Add an includeIf rule to ~/.gitconfig for ~/dev/work/
  4. Print the public key for you to add to GitHub

Add the printed public key to your GitHub account under Settings > SSH and GPG keys.

To skip SSH key generation (e.g. if you already have a key or use HTTPS):

git persona create work "Work Name" work@example.com ~/dev/work --no-ssh-key

The profile will only set user.name and user.email, without core.sshCommand.

List profiles

git persona list
Profiles:
  work
    name:     Work Name
    email:    work@example.com
    base_dir: /home/andy/dev/work
    key:      /home/andy/.ssh/id_ed25519_git_work
  personal
    name:     Personal Name
    email:    personal@example.com
    base_dir: /home/andy/dev/personal
    key:      /home/andy/.ssh/id_ed25519_git_personal

Apply a profile to the current repo

cd ~/some-repo
git persona use work

Apply a profile to a folder

git persona use-folder work ~/projects/client-a

Any git repo under ~/projects/client-a/ will automatically use the work profile.

Show the current profile

git persona current
Current profile: work
  name:  Work Name
  email: work@example.com
  key:   /home/andy/.ssh/id_ed25519_git_work

Delete a profile

git persona delete work

This removes the profile config and includeIf entries. By default, the SSH key is kept — deleting it could break access to remote repos if the key is in use. The base directory is not removed.

To also remove the SSH key pair:

git persona delete work --with-keys

Show version

git persona version

How it works

git-persona uses Git's built-in includeIf directive to apply different configs based on directory paths.

When you create a profile, it generates:

~/.config/git-persona/
  profiles/
    work.conf               # profile metadata (key=value)
    work.gitconfig          # profile-specific git config
    personal.conf           # profile metadata (key=value)
    personal.gitconfig      # profile-specific git config

And adds to ~/.gitconfig:

[includeIf "gitdir:/home/andy/dev/work/"]
    path = /home/andy/.config/git-persona/profiles/work.gitconfig

[includeIf "gitdir:/home/andy/dev/personal/"]
    path = /home/andy/.config/git-persona/profiles/personal.gitconfig

Each profile config sets user.name, user.email, and core.sshCommand:

[user]
    name = Work Name
    email = work@example.com
[core]
    sshCommand = ssh -i /home/andy/.ssh/id_ed25519_git_work -o IdentitiesOnly=yes

So any repo under ~/dev/work/ automatically uses the work identity and SSH key. No per-repo config needed.

File locations

Path Purpose
~/.local/bin/git-persona The script
~/.config/git-persona/profiles/<id>.conf Per-profile metadata (key=value)
~/.config/git-persona/profiles/<id>.gitconfig Per-profile Git config
~/.ssh/id_ed25519_git_<id> Per-profile SSH key
~/.gitconfig Modified with includeIf entries

Testing

make test

Or directly:

bash tests/test_basic.sh

The test suite runs in an isolated temp directory and won't touch your real profiles or SSH keys. 70 tests covering all commands, flags, and edge cases.

Changelog

See CHANGELOG.md for version history.

Contributing

See Contributing Guide for development setup, testing, and code style.

Pull requests are welcome. Please ensure tests pass before submitting.

Documentation

License

MIT — see LICENSE

Support

If you find this tool useful, consider buying me a coffee:

Buy Me A Coffee