Never commit as the wrong you again.

A git identity guard that blocks the commit when your author identity doesn't match the repo — with rules keyed off the remote, not the directory.

npm version MIT license CI passing
$ git commit -m "fix auth bug"
✗ gitsignet: wrong identity for this remote — commit blocked
  remote  : github.com/acme-corp/widgets
  rule    : github.com/acme-*
  expected: Work Me <me@acme.com>
  current : Personal Me <me@personal.dev>
  fix     : run `gitsignet fix` to apply the expected identity
$ gitsignet fix
✓ applied the expected identity (local git config):
    user.email → me@acme.com

Why git already has includeIf

git config includeIf can switch identity automatically — but it has three holes that bite you exactly when it matters:

It keys off the directory

Clone a work repo into ~/personal/ by mistake and includeIf silently picks the wrong identity. gitsignet keys off the remote URL — the repo is what it is no matter where it lives on disk.

It's silent

You only learn the identity was wrong after the commit is pushed with your personal email on a work repo. gitsignet is loud: doctor tells you up front, and the guard fails the commit.

It never blocks

A fresh clone with no user.email set will happily author commits. includeIf won't stop it. gitsignet's pre-commit hook exits non-zero on a mismatch or a missing identity.

Zero-config doctor

Run gitsignet doctor anywhere and it explains the identity you're about to commit as, the parsed remote, the matching rule, and whether it's OK — before you've written a single config line.

Install

# install globally
npm install -g gitsignet

# …or run without installing
npx gitsignet doctor

Quick start

# 1. See who you're about to commit as, and why
gitsignet doctor

# 2. Write a global config with your identities + rules
gitsignet init --global

# 3. Turn on the pre-commit guard in a repo
gitsignet install

Keep one global config with all your identities and you never think about it again — every repo you clone gets checked against its own remote.

Configuration

A .gitsignet.json in the repo overrides a global config at ~/.config/gitsignet/config.json. Rules match top-to-bottom; first match wins.

{
  "strict": false,
  "profiles": {
    "work":     { "name": "Work Me",     "email": "me@acme.com" },
    "personal": { "name": "Personal Me", "email": "me@personal.dev" }
  },
  "rules": [
    { "remote": "github.com/acme-*",     "profile": "work" },
    { "remote": "github.com/my-username", "profile": "personal" },
    { "remote": "gitlab.com/**",        "name": "Personal Me", "email": "me@personal.dev" }
  ]
}

remote is a glob matched against host/owner/repo, host/owner, and host. * matches within one path segment; ** crosses /. With strict: true, a commit to any remote that matches no rule is blocked.

Commands

CommandWhat it does
gitsignet doctorExplain the identity you're about to commit as, the parsed remote, the matching rule, and whether it's OK. Warns when a later rule is shadowed by an earlier broad one. Never fails a commit.
gitsignet checkThe guard. Exits non-zero on a mismatch or strict violation. --hook stays quiet on success.
gitsignet fixApply the identity the matching rule expects (sets user.name/user.email). --global writes global config. Refuses when no rule matches.
gitsignet installAdd the guard to this repo's pre-commit hook (honours core.hooksPath). Idempotent; preserves an existing hook.
gitsignet uninstallRemove the guard from the pre-commit hook.
gitsignet initWrite a sample config. --global writes it to your XDG config dir.

The installed hook calls gitsignet if it's on PATH, else falls back to npx --no-install gitsignet — so it works whether the tool is installed globally or as a dev dependency.