- Rust 80.2%
- Shell 9.3%
- NSIS 7.9%
- Makefile 2.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .cargo | ||
| .forgejo/workflows | ||
| .github/workflows | ||
| installers | ||
| packaging/aur | ||
| src | ||
| tests | ||
| .gitattributes | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CHANGELOG.md | ||
| identities.example.json | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
git-identity
Pick the right Git identity for each repository, and stop committing with the wrong email.
If you have a personal account, a work account and maybe a few open-source ones, sooner or later you push a commit signed with the wrong address. git-identity keeps your identities in one file and sets the right user.name, user.email and signing key on each repository, either from a quick fuzzy picker or automatically from the remote URL.
It is a single small binary. The only thing it needs at runtime is git.
$ git identity
? Select git identity (suggested: Work) ›
❯ Work | Jane Doe <jane@company.com>
Personal | Jane Doe <jane@example.com>
Identity set for this repo:
user.name = Jane Doe
user.email = jane@company.com
Installation
Prebuilt binaries for every release are on the GitHub releases page, which has every platform. The Forgejo releases carry the Linux and Windows x86_64 builds.
Package managers
| Where | Package | Command |
|---|---|---|
| crates.io | git-identity-manager |
cargo install git-identity-manager |
| AUR (Arch, Manjaro, CachyOS...) | git-identity-manager-bin (prebuilt) |
yay -S git-identity-manager-bin |
| AUR | git-identity-manager (built from source) |
yay -S git-identity-manager |
The package is called git-identity-manager because git-identity was already taken on crates.io and the AUR, but the command it installs is still git-identity. The AUR packages conflict with the unrelated AUR git-identity package, which installs a command with the same name.
Windows
Download and run git-identity-x86_64-setup.exe (or the aarch64 one on ARM devices).
The installer works per user, so it does not ask for admin rights. It adds the program to your PATH and shows up in Apps & features if you want to remove it later.
For a silent install, pass /S:
.\git-identity-x86_64-setup.exe /S
If you would rather not install anything, grab the portable .zip and put git-identity.exe somewhere on your PATH.
Linux and macOS
curl -fsSL https://raw.githubusercontent.com/Dxsk/git-identity-manager/main/installers/install.sh | sh
The script downloads the archive that matches your system, checks it against the release's SHA256SUMS, and puts the binary in ~/.local/bin. You can change that with PREFIX, and pin a release with VERSION:
curl -fsSL https://raw.githubusercontent.com/Dxsk/git-identity-manager/main/installers/install.sh | PREFIX=/usr/local VERSION=v1.1.0 sh
From source
You need a Rust toolchain.
make install # builds and installs to ~/.local/bin/git-identity
make install PREFIX=/usr/local # or anywhere else
make uninstall
Cargo works too, from crates.io or straight from the repository:
cargo install git-identity-manager
cargo install --git https://github.com/Dxsk/git-identity-manager
Verifying a download
Every release ships two checksum files:
SHA256SUMSlists the archives and installers you download.SHA256SUMS-binarieslists thegit-identitybinary inside each archive, as<target>/git-identity. Use it to check a binary you already extracted or installed.
On Linux and macOS:
sha256sum --ignore-missing -c SHA256SUMS # macOS: shasum -a 256 --ignore-missing -c SHA256SUMS
On Windows:
(Get-FileHash .\git-identity-x86_64-setup.exe).Hash.ToLower()
(Get-FileHash "$env:LOCALAPPDATA\Programs\git-identity\git-identity.exe").Hash.ToLower()
Then compare the result with the matching line in the checksum file.
Getting started
Add your first identity. Run it inside a repository and it suggests your current name, email and a remote pattern based on origin:
git identity add
Or do it in one line, for scripts and dotfiles:
git identity add Work --name "Jane Doe" --email jane@company.com --remote 'github\.com[:/]my-company/'
From then on, run git identity inside any repository to choose who you are there. If you prefer editing the file by hand, git identity edit opens it in your editor.
Usage
The binary is called git-identity, so Git picks it up as a subcommand. git identity and git-identity do the same thing.
| Command | Shortcuts | What it does |
|---|---|---|
git identity |
Opens the fuzzy picker | |
git identity use <label> |
sw, switch |
Applies an identity by its label (case does not matter) |
git identity auto |
Applies the identity whose remotes match origin |
|
git identity list |
ls |
Lists your identities |
git identity current |
cur, whoami |
Shows the identity set on this repository |
git identity unset |
Removes it, so the global config applies again | |
git identity add [<label>] |
new, append |
Adds an identity (see below) |
git identity remove [<label>] |
rm |
Removes an identity, or lets you pick one |
git identity edit |
e |
Opens the config file in your editor |
git identity hook |
Installs a reminder hook (see below) | |
git identity init |
Creates the config file from a template | |
git identity path |
Prints the config file location | |
git identity help |
h |
Shows the built-in help |
The old --list, --current, --unset and --hook flags still work, so existing aliases and scripts keep running.
Options for add
| Option | |
|---|---|
-n, --name <name> |
Value for user.name |
-e, --email <email> |
Value for user.email |
-k, --signing-key <key> |
Signing key |
-r, --remote <regex> |
Remote pattern, can be given several times |
Run add with no options and it walks you through every field. If you pass some options, it only asks for what is still missing. Outside a terminal it never asks, and fails if the label, name or email is missing.
add and remove rewrite the config file but keep any extra fields you added by hand.
Note
Use
git identity help(orgit-identity --help) to see the help. Git catchesgit identity --helpbefore it reaches the tool and looks for a manual page instead, which does not exist.
Configuration
Config file format
{
"identities": [
{
"label": "Work",
"name": "Jane Doe",
"email": "jane@company.com",
"signingKey": "ssh-ed25519 AAAA...",
"remotes": ["github\\.com[:/]my-company/"]
},
{
"label": "Personal",
"name": "Jane Doe",
"email": "jane@example.com"
}
]
}
| Field | Required | Description |
|---|---|---|
label |
✓ | The name you see in the picker and pass to use |
name |
✓ | Value for user.name |
email |
✓ | Value for user.email |
signingKey |
GPG or SSH key used to sign commits. Setting it also turns on commit.gpgsign and picks gpg.format for you: ssh when the key starts with ssh- or key::, openpgp otherwise. |
|
remotes |
Regular expressions checked against the origin URL. The first identity that matches is suggested in the picker and used by auto. |
Editing the file
git identity edit opens the config in your system's default editor: the app tied to .json files on Windows, the default text editor on macOS, and whatever xdg-open picks on Linux. Those apps keep running in the background, so the tool waits for you to press Enter once you have saved.
If you set an editor for Git (GIT_EDITOR, core.editor, VISUAL or EDITOR), that one is used instead and the tool simply waits for it to close. This is also what happens over SSH or anywhere without a desktop session. For example, to use VS Code:
git config --global core.editor "code --wait"
Once you are done, the file is checked. If it is not valid you can reopen it to fix the mistake. If you give up, the previous config is restored and your edit is kept in identities.json.rejected, so nothing is lost and the tool keeps working.
If the file does not exist yet, it is created from the example template first.
Where the config lives
git-identity looks for the file in this order and uses the first one that applies:
- The path in
GIT_IDENTITY_CONFIG $XDG_CONFIG_HOME/git-identity/identities.json, ifXDG_CONFIG_HOMEis set- The default location for your system:
- Windows:
%APPDATA%\git-identity\identities.json - Linux and macOS:
~/.config/git-identity/identities.json
- Windows:
Picking the identity automatically
When an identity has remotes patterns and one of them matches the repository's origin URL, the picker opens with that identity already selected. You only have to press Enter.
To skip the picker altogether, for example in a script or a Git hook, use:
git identity auto
It fails with a clear message when no pattern matches, so it is safe to chain.
Reminder hook
Inside a repository, git identity hook adds a small post-checkout hook. After each checkout, it prints a reminder if no local identity is set yet.
The hook is a plain POSIX sh script. Git for Windows runs these out of the box, so it behaves the same on every platform. If you already have a post-checkout hook, the reminder is appended to it instead of replacing it.
Development
Building and testing
make build # optimized binary in target/release/
make test # unit and integration tests
make coverage # tests plus line coverage (needs cargo-llvm-cov)
make lint # rustfmt and clippy
The integration tests run the real binary against throwaway repositories, with your global Git config kept out of the way.
Line coverage is around 74%. The Forgejo CI measures it on every push and prints the per-file figures in the "Tests and coverage" step. What is left out is mostly the interactive part (the picker, the add wizard, opening the system editor), which needs a real terminal or desktop and is checked by hand. For a small CLI like this one, chasing 100% is not worth it.
To build the Windows installer yourself, install NSIS and run:
cargo build --release
makensis /DVERSION=1.1.0 installers\git-identity.nsi
The setup file ends up in dist\.
CI and releases
The project lives on Forgejo and is push-mirrored to GitHub. Each side has its own pipeline:
Forgejo (.forgejo/workflows/) |
GitHub mirror (.github/workflows/) |
|
|---|---|---|
| On every push | Format, lint and tests on Linux | Format and lint, tests on Linux, macOS and Windows |
On a v* tag |
Linux x86_64 and aarch64, Windows x86_64 and its installer, all cross-compiled from one Linux runner | The same, plus macOS (Intel and Apple Silicon) and Windows ARM |
Both releases include SHA256SUMS and SHA256SUMS-binaries.
Cutting a release
-
Describe the changes under
## Unreleasedin CHANGELOG.md. -
Run the release target with the new version:
make release V=1.1.0It sets the version in
Cargo.tomlandCargo.lock, turns theUnreleasedheading into1.1.0 (date), then commits and creates the signedv1.1.0tag (git tag -s, so a GPG signing key is needed). Nothing is pushed yet, so you can still check the result. -
Push to Forgejo:
git push --follow-tags
The tag starts the Forgejo release, and the mirror carries it to GitHub, which starts the GitHub one. Both refuse to run if the tag does not match the version in Cargo.toml.
-
Once the GitHub release has all its assets, publish the packages:
cargo publish # crates.io sh packaging/aur/render.sh 1.1.0 --publish # AUR, needs your AUR SSH keyWithout
--publish,render.shonly writes thePKGBUILDand.SRCINFOfiles todist/aur/for review.
Since the mirror overwrites GitHub on every sync, never commit or tag directly on GitHub.