7

Following this SO post and the linked guidance, I set up a condition configuration like the following...

$ cat ~/.gitconfig 
[user]
    name = Random J. Hacker
    email = RandomJ@hack.er
[includeIf "gitdir:~/work/*"]
    path = ~/work/.gitconfig

$ cat ~/work/.gitconfig 
[user]
    name = Serious Q. Programmer
    email = serious.q@programmer.biz

In this way, all of the repositories I do clone when I'm working for Programmer Co. get my @programmer.biz work email address assigned as the default --author credential; and every random repo I clone to my desktop or /tmp or ~/.vscode or wherever gets my super legit @hack.er credential assigned as the author.

Unfortunately, I noticed the following behaviour...

$ git clone git@github.com:programmerbiz/repo.git
$ cd repo/
$ git config --list | grep user
user.name=Random J. Hacker
user.email=RandomJ@hack.er
user.name=Serious Q. Programmer
user.email=serious.q@programmer.biz

Oh no! My @hack.er user is picked up by the business repo!

I would like to automatically configure one and only one default [user] for all repos without resorting to a bash script. Is there an includeIf.Not operator, [else] block syntax, or similar that I can use in ~/.gitconfig to achieve this? The conditional includes documentation does not appear to support this use case.

Peter Vandivier
  • 421
  • 4
  • 20
  • 2
    How about having a normal `[user]` section with the else-part, and then an includeif section with the specific part, this seems to work on Windows at least. – Lasse V. Karlsen Jul 30 '19 at 16:27
  • Did you try `includeIf` as described here? https://stackoverflow.com/a/46239540/3216427 – joanis Jul 30 '19 at 18:05
  • Can't you define it globally to `@fun.times` and follow that by the `includeIf` which overrides the name and email only when it applies? The "else" would be implicit in the preceding global settings. Actually, that's exactly what @Lasse suggested above. – joanis Jul 30 '19 at 19:14
  • Ah OK. I get it now. It would be worth editing the question to mention it there, since it wasn't clear you had tried that seemingly obvious solution and what was wrong with it. Interesting question, I hope someone provides a working answer. – joanis Jul 30 '19 at 19:23
  • Next question: when I reproduced your scenario, I also got the double creds in `git config --list`, but when I did `git commit` it used the right credentials. It looks to me like the later occurrence overrides the earlier one, even if `git config --list` still lists them both. – joanis Jul 30 '19 at 20:10
  • @joanis `git log` shows the last author listed on very cursory testing for me as well. Given the existence of multi-author commits [1](https://help.github.com/en/articles/creating-a-commit-with-multiple-authors) [2](https://stackoverflow.com/questions/7442112), I'd rather not have the cached credential "_just hanging around_" and _hope_ that it doesn't get picked up by some process that shouldn't see it. – Peter Vandivier Jul 30 '19 at 20:14
  • Well, the problem is that there is no "else" or "ifnot", you have includeIf and that's it. – Lasse V. Karlsen Jul 30 '19 at 20:46
  • 1
    @PeterVandivier Try `git log --format=raw` to convince yourself it's safe: according to `git log --help`, "The raw format shows the entire commit exactly as stored in the commit object." On my end with your scenario reproduced, I only see the "work" identity in my test commit in the `work` folder. – joanis Jul 31 '19 at 13:36

2 Answers2

4

What is the output of git config --list --show-origin | grep user?
You should see where the configurations are defined.

I would like to automatically configure one and only one default [user] for all repos

In this case, remove all the above users configuration and set a single entry in your global config

# Use the `--global` to store it under your user account configuration
# and it will be used as the default for all of your projects unless you
# define it in your local `.git/config`

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

---- 
# For specific project use the `--local` flag (will be stored in your `.git/config`

git config --local user.name <....>
git config --local user.email <....>
CodeWizard
  • 92,491
  • 19
  • 110
  • 133
  • 1
    Using `git config --local` per-repo is rather what I was trying to avoid with the conditional global config. +1 however - I never knew about the `--show-origin` option. Using this flag, it actually looks like locally setting a `[user]` doesn't "overwrite" the default global config setting as I was hoping/expecting. Perhaps I need to read up a bit on attribute precedence for git repos. – Peter Vandivier Jul 31 '19 at 07:18
1

The problem is the way you are specifying the gitdir, I had the same issue, and the path (full or relative) should end with a slash.

You have gitdir:~/work/*

This is how it should look:

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

You can then go to the directory and check if it worked:

cd ~/work
git config --list | grep user

Cheers!

Willemoes
  • 4,206
  • 1
  • 26
  • 20