Introducing `guser`

September 7, 2020

Also published to Dev.to

Do you manage multiple Git users on a single machine? Do you often switch between work projects and side projects and configure different repositories to use different accounts?

If so, you might benefit from guser, a small CLI tool that helps make Git user-switching a tiny bit easier by remembering user/email combinations you’ve used in the past.

As an added bonus, if you try out guser you’ll also be in a position to give me feedback on my very first CLI tool— and also the first project I’ve published to NPM 😎.

Configuring Git users

You probably recall configuring Git when first setting up your development environment: you likely set up an SSH key to allow Git to authenticate with Github or another remote, and you probably also configured Git with a username and email used to sign your commits.

This second step you likely performed with the git config tool that comes with Git, and it probably looked something like this:

$ git config --global user.name "Margaret Hamilton"
$ git config --global user.email margaret@hamilton.com

These commands created and/or edited a configuration file, .gitconfig, in your home directory:

$ cat .gitconfig
[user]
	name = "Margaret Hamilton"
	email = "margaret@hamilton.com"

This config file in your user directory is one of three such possible files Git might reference when authoring a commit to determine the username and email to use:

  1. /etc/gitconfig/, which configures Git for every user on the system
  2. ~/.gitconfig, the aforementioned file, specific to the user who the containing directory belongs to
  3. [repository path]/.git/config, which sets a configuration specific to a particular repository.

When you set up Git using git config --global, you told the config tool to create or write to the second, user-level file. But you might have passed --system to write to the first system-wide file or --local to write to a config file in a repo, provided your current working directory is inside such a repo.

Importantly, values from a local config file (if present) override those from a user config file (if present), both of which in turn override values from a system-level config (if present). Note that we say “values”, here: if a local file lacks a value for user but has a value for email, the local email will be used but the user will be pulled from either the user- or system-level config files, assuming one of these has a user present.

Managing multiple users with guser

We often find ourselves with a default user and email set in ~/.gitconfig which we wish to override at the level of an individual repository.

Perhaps we have a work email and username set in our user directory, but also wish to work on a personal project and author commits that match the username of a personal Github account. Or perhaps we need to manage multiple work-related Git accounts with different usernames— for example, one for a Github enterprise instance and another authorized to access a private organization on github.com.

Ordinarily, this is as straightforward as running git config with --local flags for the user and email when inside the repository that needs to override user- or system-level configs. But this can get tedious when we have many accounts to manage or when we frequently clone new repositories (as .git/config is not committed or pushed to the remote).

This is where guser can help. It’s a thin wrapper over these git config commands coupled with a means to persist frequently-used config/email pairs to a config file in your user directory, all behind an interactive CLI that lets you quickly choose the config to set:

$ guser
Checking for local git config...
No local user set
No local email set
? What would you like to do? › - Use arrow-keys. Return to submit.
❯   Set local git user config
    Remove user config from guser
    List configs in guser
    Add user config to guser

Alternatives to guser

Despite being a CLI tool, guser doesn’t really follow the unix philosophy. While it does one thing and just one thing well, it opts for an interactive interface over pipeability and composability.

If you would prefer a similar tool that can be driven entirely via flags and arguments, check out WindomZ’s gituser.js.