RotatingPieces RotatingPieces - 1 month ago 7
Git Question

I use several computers with different gitconfigs. How do I stop leaking my e-mail addresses to GitHub?

I have a work computer where

$HOME/.gitconfig
has
user.email
to
RotatingPieces@work.tld
. My home computer has
$HOME/.gitconfig
has
user.email
to
Rotating.P@SuperKawaiiAnimeWeb.net
. And there is the virtual machine with
R.Pieces@DogeMemes.net
. And the laptop has... .

These e-mail addresses are correct for most of the repositories cloned on these machines. But sometimes I do mix up what I am doing on what machine. Doing work stuff at home and the other way around.

So when I do something in my public GitHub/BitBucket/GitLab/Whatever repository at I then commit as
RotatingPieces@work.tld
. Working from home creates commits as
Rotating.P@SuperKawaiiAnimeWeb.net
. Because of this I accidentally link these two e-mail addresses together. It happens by accident all the time.

Is there some way to stop this? What can I do to stop myself from leaking my e-mail addresses when working on the same repository on different machines?

Things that don't work:


  • Changing
    $HOME/.gitconfig
    files. These e-mail addresses are correct for most of the repositories cloned on these machines.

  • Using
    git commit --author=...
    . I would forget the
    --author
    option all the time.

  • Setting an e-mail address in
    .git/config
    of the cloned repository. This only works for this machine for this repository. I would have to remember that for every time I make a new clone of a repository. Too easy to forget.



The best solution would be a server-side or client-side commit hook that you can just commit into a repository which then is run by git. Or some hook or e-mail address filter I could activate in the GitHub web UI. However such a thing probably doesn't exist for obvious abuse reasons.

Anyone got any ideas for a solution?

Answer

I've had the same issue for a while: I want different email addresses to be used for work projects, open source projects, personal projects, and so on, and I want it to be set automatically based on folder structure rather than remembering to do it per repo.

This solution will automate the process of setting the email on a per-repo basis. One assumption I'll make is that you have divided your projects into folders based on owner (or rather, based on the email address you want to use). E.g.:

code/
  work/
    (All subfolders use work email.)
  open-source/
    (All subfolders use open source email.)
  personal/
    (All subfolders use personal email.)

According to the Git Docs, post-checkout hooks are run after a git clone command, so we can use a global post-checkout hook to set the email per-repo.

First, do:

git config --global init.templatedir '~/.git_template'

(From Git commit hooks - global settings.)

Then create that folder and a subfolder called hooks. Add the following script as ~/.git_template/hooks/post-checkout:

#!/bin/bash
# Automatically set Git config values from parent folders.

dir=$(pwd)
while [ "$dir" != "/" ]
do
  # First directory would be the new Git repo, so skip it.
  dir=$(dirname $dir)
  if [ -f $dir/.gitconfig ]
  then
    for config in $(git config --file $dir/.gitconfig --list)
    do
      var=$(echo $config | cut -d = -f 1)
      value=$(echo $config | cut -d = -f 2)
      actual=$(git config $var)
      if [ "$actual" != "$value" ]
      then
        git config $var $value
      fi
    done
  fi
done

(You can also find this script at my GitHub repo git-template.

Now, for each of the folders I mentioned, add a .gitconfig file with the appropriate email. Do e.g.:

git config --file /mnt/data/code/open-source/.gitconfig user.email "open-source@scott-weldon.com"

Now, as long as you git clone into the right folder, your repos will automatically have the correct email address set in the local config.

Bonus features:

  1. For those repos you have already cloned, you can just cd to the relevant Git directory and call ~/.git_template/hooks/post-checkout directly to update the email.

  2. You can add whatever config you want to the .gitconfig files, and those settings will also be added to the repo.

Known issues:

  1. Currently it searches the directories from pwd to /, when it should reverse the order. This shouldn't be hard to fix, so I'll add that to my solution at some point.

  2. The script will be executed after every checkout, not just after initial clone, so there may be a small performance penalty. However, the conditionals ensure that it won't set the value if it has already been set, or if no .gitconfig file is found.

  3. Due to #2, there isn't a way to override the settings with repo-specific values.