Hacker News new | ask | show | jobs
by edavis 849 days ago
For the "I want to use different emails for different repos" issue, I've seen the `includeIf` technique but it felt fiddly. What I've done is set `user.useConfigOnly = true` and commented out `user.email` in ~/.gitconfig.

Now the first time I commit in a new repo, it errors out with "Author identity unknown" and I punch in "git config user.email ADDR" for the email I want to use and re-run the commit.

3 comments

During my consulting time, I had to do this a lot. So I wrote a blog post for myself on how to do this effectively - https://www.shirishpadalkar.com/using-separate-git-identitie...
I also don't like the `includeIf`, but I ended up with a completely different way of doing things.

I just use different accounts depending on the context, usually by either SSH or by starting a Docker container with all the environment already configured.

At least for me, using different identities[1] when I want to use different identities[2], seems less brittle and less likely for my future self to accidentally forget to do something (e.g. change a config when I reinstall an OS).

[1]: OS user, directly (SSH) or indirectly (container).

[2]: Email address, username, etc.

Huh. How many repos do you have? And how many emails? I have... A lot of repos. And two emails.
Two is still more than one, and it seems reasonable to, for example, keep work separate from personal stuff.
Yeah, but the includeIf solution has me typing my emails once each, rather than once each for something like 100+ repos.
I occasionally clone repos into /tmp for some small tweaks without switching branches or whatever, and that’s usually when I commit with the wrong email. Neither includeIf nor useConfigOnly are ideal in this scenario because a) it’s cloned in a generic location that can’t be differentiated using path-based includeIf, or b) manually setting it multiple times for the same repo is even more annoying.

I’ve tried conditionally setting email based on the remote [1], but for some reason I did not manage to make it work. I didn’t try too hard, and I might try again with more patience.

[1] https://www.brantonboehm.com/code/conditional-git-config/

I mostly use `ghq` to clone repositories (and have a few `fzf` aliases based on that, like `ghqcd` to `cd` to some repo)

    [ghq] # https://github.com/x-motemen/ghq#configuration
        root = ~/dev
Sometimes, from my personal machine, I need to check something work-related ; then on my personal machine, I checkout in `~/dev/myorganization/`. Inversely, it happens sometimes that at work I need something I wrote for myself ; then on my work machine, I checkout in `~/dev/myusername/`.

This allows me to use `gitdir:` rules that handle anything `~/dev`, and I have fallbacks for everything else (who never checkouts in `tmp`?).

    #
    # Superman vs Clark Kent
    #
    # Debug Includes with: git config --list --show-origin

    # the default identity, for checkouts outside of `~/dev`
    [include]
        path = ~/.config/git/gitconfig-default

    # on my work machine, this defines Clark Kent ; on my personal machine, this defines Superman (or is  it the reverse?)
    # this one is not commited in my dotfiles
    [include]
        path = ~/.config/git/gitconfig-local

    # work-related repos on personal machine
    [includeIf "gitdir:/home/myusername/dev/myorganization/"]
        path = ~/.config/git/gitconfig-myorganization
    [includeIf "gitdir:/home/myusername/dev/gitlab.com/myorganization/"]
        path = ~/.config/git/gitconfig-myorganization

    # personal repos on my work machine
    [includeIf "gitdir:/home/myusername/dev/myusername/"]
        path = ~/.config/git/gitconfig-myusername
    [includeIf "gitdir:/home/myusername/dev/gitlab.com/myusername-namespace/"]
        path = ~/.config/git/gitconfig-myusername
This works nicely since years^W `includeIf` was a thing.

However, there are situations at work where I'm on a server where I didn't created `~/.config/git/gitconfig-local` (which is a manual step I always forget) and any commit from `/usr/local/src/something/` will end up configured with Superman identity.

I found out about `hasconfig:` some time ago, and took note of it for when the option would hit `git` from Debian Stable ; your comment comes the day after I accidentaly commited as Superman on some work repo checked outside of `~/dev/`. Time to add more rules!