Readit News logoReadit News
varl · 5 years ago
I found this user management strategy somewhere, and it's been working great for me:

  git config --global --unset user.name
  git config --global --unset user.email
  git config --global --unset user.signingkey

  git config --global user.useConfigOnly true

  git config --global user.<id>.name "<name>"
  git config --global user.<id>.email "<email>"

  git config --global alias.identity '! git config user.name "$(git config user.$1.name)"; git config user.email "$(git config user.$1.email)"; :'
So given that I have created two users, e.g. personal and work I run:

  git identity work
in repos that need the work name/e-mail, and

  git identity personal
in the ones that are private.

emanlin · 5 years ago
I find it much easier to use direnv and set GIT_AUTHOR_EMAIL in each of ~/work/.envrc and ~/personal/.envrc No need to reconfigure every repo this way.
augusto-moura · 5 years ago
Git has conditional includes based on path[1]. My configuration is like:

On ~/.gitconfig

  [user]
    name = personal
    email = personal@example.com

  [includeIF "gitdir:~/workspace/"]
    path = ~/work.gitconfig

Then on ~/work.gitconfig

  [user]
    name = workname
    email = work@example.com
[1] https://git-scm.com/docs/git-config#_conditional_includes

cbcoutinho · 5 years ago
I do the same. Also remember the following keyword if you use nested .envrc files: source_up

If you don't use this in any nested envrc files, the settings don't carry over which means your git settings are not maintained. It is kind of an escape hatch as the parent files are not verified in the same way normal envrc files are, but I have found the trade off to be worth it

gioele · 5 years ago
I also appreciate using `git whoami` to check the current identity settings:

    $ git whoami 
    GIT_COMMITTER_IDENT=Mel Smith <mel@example.org>
    GIT_AUTHOR_IDENT=Mel Smith <mel@example.org>
`whoami` can be implemented via a simple alias:

    git config --global alias.whoami = "! git var -l | grep '^GIT_.*_IDENT'"

corytheboyd · 5 years ago
Nice! I was thinking of something like this recently, but decided instead to completely divorce personal and work projects. It’s nice to close the work laptop and go open the personal laptop knowing it’s impossible to cross the streams, as well as for the ritual.
gumby · 5 years ago
Good idea as it makes the trees "self describing".

But: does this edit a file that can appear in .gitignore or are you uploading this to affect all your collaborators?

Ajedi32 · 5 years ago
It writes to `.git/config` in the local repo. (.git/ is ignored by default, obviously.)
jolmg · 5 years ago
> git config --global alias.identity '! git config user.name "$(git config user.$1.name)"; git config user.email "$(git config user.$1.email)"; :'

Why `; :` at the end?

varl · 5 years ago
I'm not entirely sure, but `:` means "true" in bash, and if I omit it, something like this happens:

  $ git config alias.foo '! echo "$1";'
  $ git foo bar
  bar
  echo "$1";: bar: command not found
Whereas if I end with `; :` then it works as expected:

  $ git config alias.foo '! echo "$1"; :'
  $ git foo bar
  bar
It seems to execute the last argument (`bar`) as a command without the `:` at the end, and I don't have a `bar` command on my PATH so it angrily fails with exit code 127. If it instead executes `:` however, that will make it happily exit with 0.

It seems to be a Git alias quirk, but I may be incorrect here.

diegoholiveira · 5 years ago
I've been doing the same, this it's pretty good IMO.

Deleted Comment

pavlo · 5 years ago
This is a great looking tool.

What I have been doing by hand for some time is putting code for different customers in different directories and having a conditional in `~/.gitconfig` to determine what config applies there:

    [includeIf "gitdir:~/projects-private/**"]
      path = ./.gitconfig-private

    [includeIf "gitdir:~/projects-client/**"]
      path = ./.gitconfig-work
Then in .gitconfig-private or .gitconfig-work I have all the usual gitconfig settings that apply, for example the [user] section...

Switching to the right directory thus automatically changes the settings.

diggan · 5 years ago
The CLI tool looks very great indeed and handy when you keep all the projects in the same top-level directory, or need to be able to change identity while in the same repository.

However, your .gitconfig setup is (for me) way nicer as I already have things split up by GitHub organization, and now my identity can change without having to do anything at all.

So thanks for sharing that, had no idea it was possible.

geongeorgek · 5 years ago
Thanks for sharing this. This was what I was missing. Should've done proper research before building.

I'd still think the cli could be useful in some situations. but I agree with others about how big this had to be because I used node.

pavlo · 5 years ago
I think a tool that has a similar UX as your is handy if a person don't care or want to memorise the gitconfig documentation to figure this out. Which, I think, is true even for most of the developers. I have found this one out by a coincidence myself.
gru · 5 years ago
This is the approach that works very well for me. Especially since I keep my repos cloned into a directory structure inspired by "go get" using https://github.com/grdl/git-get
Foxboron · 5 years ago
A 1000 line YARN lock file for something that would be roughly 20 lines of bash is amazing and terrifying at the same time.
cdubzzz · 5 years ago
Let’s see the 20 lines of bash that replicate all the features of this utility. Should fit in an HN comment nicely.
boogies · 5 years ago
> roughly 20 lines of bash

various permutations of which were posted an hour ago and are currently higher than this comment, so I’m confused why multiple people asked to see them ~30½ minutes ago

cdubzzz · 5 years ago
I asked because none of the posted permutations offer the same feature set. Specifically, the nice thing about this utility (and reason for the dependencies) is interactive adding and selecting of identities. If this can replicated in bash, I am legitimately interested in seeing it, 20 lines or not.
gnagatomo · 5 years ago
Can you show us your take on the bash solution?
lprd · 5 years ago
Welcome to modern javascript development.
oefrha · 5 years ago
Without using include in gitconfig:

  #!/usr/bin/env zsh
  case $1 in
  foo)
      git config user.name 'John Doe'
      git config user.email john@example.com
      git config user.signingKey 0xFFFFFFFF
      ;;
  bar)
      git config user.name 'Jane Doe'
      git config user.email jane@example.com
      git config user.signingKey 0xEEEEEEEE
      ;;
  baz)
      git config user.name 'My Dog'
      git config user.email dog@example.com
      git config user.signingKey 0xDDDDDDDD
      ;;
  *)
      echo "usage: git-user foo|bar|baz" >&2
      exit 1
      ;;
  esac
Done.

Btw probably want to add signingKey support.

archseer · 5 years ago
andreineculau · 5 years ago
!!! which not only covers the identity scenario but the whole configuration of git, which can be indeed very different from repo to repo, from company to company
mr-karan · 5 years ago
I currently use [karn](https://github.com/prydonius/karn) to manage multiple `git` identities. Works pretty nice.
captn3m0 · 5 years ago
+1 for karn. Works nicely with any directory hierarchy.

Deleted Comment

gurjeet · 5 years ago
I rely on Git's `user.useConfigOnly` option to force myself to set my email per repository. This is what my `user` section in ~/.gitconfig looks like.

  [user]
    name = Gurjeet Singh
    # Tell Git to _not_ guess my name and email based on `whoami` and `hostname`
    useConfigOnly = true
With this in place, whenever I try to commit for the first time in a repository, Git prompts me

  *** Please tell me who you are.*
I then add an email address to the repo-local config based on whether it's work or personal project.

  git config user.email me@example.com