gitprofiles
gitprofiles is CLI for managing multiple Git identities with local enforcement.
The intended workflow is:
- first, define profiles once
- then, set one profile per repository
Commits/pushes are blocked when profile state is missing or mismatched, although, there are some limitations. Please read below.
Compatability
The only supported platforms are:
- Linux/POSIX shell environments
The program may or may not work on other platforms. Support for them is not planned either.
Install and Run
Build locally:
Run the binary:
Quickstart
- Initialize global integration:
- Create a profile (interactive):
- In each repository, select a profile:
- Validate repository state:
Commands
gitprofiles initgitprofiles creategitprofiles set-profile <name>gitprofiles checkgitprofiles listgitprofiles remove <name>
How Enforcement Works
The way gitprofiles was designed is straightforward. It does not try to wrap Git or replace its behavior, but instead, it adds a guardrail at the two moments where identity mistakes usually matter most. They're during, 1: creating commits, and, 2: pushing changes.
When you run gitprofiles init, the tool creates two hooks under ~/.config/gitprofiles/hooks: prepare-commit-msg and pre-push. Both hooks call gitprofiles check.
gitprofiles check is the policy gate. It reads your repo's local gitprofiles.profile, user.name, and user.email, then compares that state against the profile definition in ~/.config/gitprofiles/profiles.toml. If the profile marker is missing, if the profile name is not found in the TOML file, or if local name/email drift from that profile, the operation is rejected.
So practically, once you run gitprofiles set-profile <name> in a repo, the checks keep that repo locked to the specified profile, unless you intentionally change something.
Nuance
There is one behavior that can look confusing if it happens to you... During init, gitprofiles sets user.useConfigOnly=true globally. This is so that Git doesn't aut-guesses identity from the system username/hostname. That means in a repository where you have not set a local profile yet, and if global user.name/user.email are unset, a commit may fail with Git's own message:
fatal: no email was given and auto-detection is disabled
This is expected, and it is still policy enforcement doing its job.
The "fix" is to run gitprofiles set-profile <name> in that repository, then gitprofiles check, and try again. After local profile setup is valid, commits/pushes will work. And you do not need global user.name/user.email, it's optional.
Limitations
-
There is no client-side hook for local
git tagcreation. So tag creation itself is not blocked. The main identity risk is with annotated tags, because they embed tagger identity metadata, and that can be published when tags are pushed. -
gitprofiles is just a client-side enforcement, which is great enough. However, local hooks can be bypassed if things were invoked in ways that skip Git.
-
gitprofiles initwill refuse whencore.hooksPathis already set globally, and it will also refuse if managed hook targets already exist. This is so the program does not overwrite an existing hook setup. A hook integration mode that can coexist with pre-existing hooks (chaining instead of refusing by default) is planned.
Troubleshooting
refusing to initialize: global core.hooksPath is already set
The program detected an existing hook setup and intentionally refused to overwrite it. That is currently a hard stop by design. You need to clear or migrate that existing hooks path manually before running gitprofiles init.
missing local key 'gitprofiles.profile'
That repository has not been assigned a profile marker yet. Run gitprofiles set-profile <name> in that repo.
profile '<name>' does not exist
The profile name is not in ~/.config/gitprofiles/profiles.toml. Run gitprofiles list to see existing names, or create the profile first via gitprofiles create.
local user.name/user.email mismatch
Repository identity has drifted from the selected profile. Re-apply with gitprofiles set-profile <name>, then confirm with gitprofiles check.
fatal: no email was given and auto-detection is disabled
Git is telling you there is still no valid local identity in that repository while user.useConfigOnly=true is active. Set the repo profile and retry.