gitprofile

command module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 3, 2026 License: MIT Imports: 3 Imported by: 0

README

gitprofile

A Go CLI tool for managing multiple git identities — work, personal, open-source — each with its own SSH key, commit-signing setup, and directory routing. The right identity and key activate automatically based on which folder a repo lives in.

How it works

Two problems underlie every multi-account git setup:

  1. Git identityuser.name, user.email, and the commit-signing key. Git owns this.
  2. SSH key routing — which private key authenticates a push/pull/clone. SSH owns this, and most setups silently break here.

gitprofile solves both using git's includeIf directive. It maintains a single managed block in ~/.gitconfig:

# >>> gitprofile managed >>>
[includeIf "gitdir:~/work/"]
    path = ~/.config/gitprofile/profiles/work.gitconfig
[includeIf "gitdir:~/personal/"]
    path = ~/.config/gitprofile/profiles/personal.gitconfig
# <<< gitprofile managed <<<

Each profile's fragment carries identity, SSH command, and optional signing config:

# ~/.config/gitprofile/profiles/work.gitconfig
[user]
    name = Jane Dev
    email = jane@company.com
    signingkey = ~/.ssh/id_work.pub
[core]
    sshCommand = "ssh -i ~/.ssh/id_work -o IdentitiesOnly=yes"
[commit]
    gpgsign = true
[gpg]
    format = ssh

Any repo cloned under ~/work/ automatically gets the right name, email, signing key, and SSH key — with zero per-repo commands. IdentitiesOnly=yes ensures SSH never authenticates with the wrong account.

Installation

git clone <this-repo>
cd gitprofile
go build -o gitprofile .
mv gitprofile /usr/local/bin/

Requires Go 1.21+.

Commands

gitprofile add <name>

Interactive wizard: collects identity, host, SSH key (generate new or adopt existing), owned directories, and signing preference. Writes the profile to ~/.config/gitprofile/config.yaml, generates a gitconfig fragment, and updates the managed block in ~/.gitconfig.

gitprofile add work
# Full Name: Jane Dev
# Email: jane@company.com
# Host (github.com/gitlab.com...): github.com
# Generate new SSH key? (y/n) [y]: y
# Generated new SSH key at ~/.ssh/id_work
# Enable SSH signing for commits? (y/n) [y]: y
# Directories this profile owns? (comma-separated): ~/work,~/company
# Profile created and installed!

Then add the public key to your git host:

gitprofile key show work
gitprofile list

Lists all configured profiles with their owned directories.

gitprofile list
# - work: Jane Dev <jane@company.com> (dirs: [~/work ~/company])
# - personal: Jane <jane@personal.dev> (dirs: [~/personal])
gitprofile current

Shows which profile applies to the current directory and why.

cd ~/work/myrepo
gitprofile current
# Profile: work (Jane Dev <jane@company.com>)
# Reason: in directory ~/work (owned by profile)
gitprofile use <name>

Applies a profile as a local override in the current repo's .git/config. Use this for repos that live outside any owned directory.

cd /tmp/some-repo
gitprofile use work
# Profile config applied locally to this repo.
gitprofile clone <url> [--as <name>]

Clones a repo using a profile's SSH key from the first byte. When --as is given, the clone runs with GIT_SSH_COMMAND set and lands inside the profile's first owned directory as a subdirectory.

gitprofile clone git@github.com:company/service.git --as work
# Clones into ~/work/service with the work SSH key
gitprofile key show <name>

Prints the public key to paste into GitHub / GitLab / Bitbucket.

gitprofile key show work
# Public key for work:
# ssh-ed25519 AAAA...
gitprofile key path <name>

Prints the private and public key file paths.

gitprofile key path work
# Private: ~/.ssh/id_work
# Public:  ~/.ssh/id_work.pub
gitprofile edit <name>

Interactively update any field of an existing profile. Re-renders the gitconfig fragment and managed block.

gitprofile edit work
gitprofile remove <name>

Removes the profile, its gitconfig fragment, and its includeIf entry. The SSH key files are left untouched.

gitprofile remove work
# Profile removed.
gitprofile doctor

Diagnoses common issues:

  • Duplicate directory ownership across profiles
  • Missing or invalid SSH keys (permissions, parsability)
  • Missing gitconfig fragments
  • Live SSH connectivity test against each profile's host (ssh -T git@github.com)
  • Missing managed block in ~/.gitconfig
gitprofile doctor
# Testing ssh -T github.com using key ~/.ssh/id_work ...
# Hi janeDev! You've successfully authenticated...
# [OK] All checks passed.

Files written

Path Purpose
~/.config/gitprofile/config.yaml Profile registry
~/.config/gitprofile/profiles/<name>.gitconfig Per-profile gitconfig fragment
~/.gitconfig Managed includeIf block appended / replaced
~/.gitconfig.gitprofile.bak Backup created before each ~/.gitconfig edit
~/.ssh/id_<name> Generated ed25519 private key (0600)
~/.ssh/id_<name>.pub Generated ed25519 public key (0644)

Safety

  • Managed block — all edits to ~/.gitconfig live inside clearly-marked >>> gitprofile managed >>> sentinels. The tool only touches its own section; everything else is preserved.
  • Backup~/.gitconfig.gitprofile.bak is written before any modification.
  • Key permissions — private keys are created with 0600; the key directory is set to 0700. Existing keys are permission-fixed on adoption.
  • No clobberingadd refuses to overwrite an existing key file.
  • IdentitiesOnly=yes — injected into every sshCommand so SSH never falls back to the SSH agent and authenticates as the wrong account.

Pending / roadmap

  • signing package — allowed_signers file management and host paste hints for signing-key registration
  • hosts package — host-specific guidance (GitHub / GitLab / Bitbucket key registration URLs)
  • --force flag on add to overwrite an existing key
  • --global mode to set a catch-all default profile
  • Shell completion (cobra provides this for free)
  • Windows support (path handling and SSH command quoting)

Development

go test ./...                  # run all tests
go build -buildvcs=false .     # build binary

Tests cover config round-trips (internal/config), gitconfig fragment rendering and managed-block rewriting (internal/gitconfig), and SSH key generation and validation (internal/sshkey).

License

MIT

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL