7 ms·
Conditional Git Configuration
- blux 3y agoI did not know about `includeIf`...this allows getting rid of the hacks I used to achieve something similar, great!
- bloopernova 3y agoOh nice, this will remove an annoyance in my dotfiles repo by letting me share my gitconfig between 3 different configurations (home linux amd64 box, work macOS arm64, client macOS arm64) Thank you for sharing it!
- nerdponx 3y agoI just have a "config-private" file that I include in my main config, but I ignore it in the dotfiles repo. Git will ignore any included file if it does not exist. That lets me customize things locally without checking work details into version control.
- bloopernova 3y agoThat's a neat way of doing it, I will do the same, thank you!
- klausa 3y agoWhat do you have in your git config that requires switching over host architecture?
- bloopernova 3y agoI put those there as a way to show I couldn't just switch on $ARCH or $OSTYPE similar. I should have explained that better, sorry about that.
- klausa 3y agoAh, gotcha. I thought you might have some weird, nice needs and was curious about it :)
- dvas 3y agoUseful when you want to have multiple git accounts changing based on the path. Thanks for the share! In my case it was changing the ssh key based on the project folder.
- tux1968 3y agoman git-config, shows that so far there aren't many conditions available for testing. The location of the .git directory (as in the article). The name of the currently checked out branch. Or a pattern match against any remote URL in the configuration.
- _joel 3y agoActually useful, thanks
- matheusiacono 3y agoI use it to set my personal and my work email to different projects
- bashtoni 3y agoNice. For years I've been using [direnv](https://direnv.net/ https://direnv.net/) for this, setting environment variables which git picks up. This looks like a more feature complete equivalent, although to be honest I only really need switching of committer email and the SSH key used.
- koolba 3y agoYou don’t need for config for the SSH piece as it defers to SSH’s own config for it.
- halostatue 3y agoIf you’re using SSH for commit signing, you do need that in your git configuration.
- lathiat 3y agoFor the SSH part you can use ~/.ssh/config and it also has conditional stanzas like "Host foo.com" or "Host *.foo.com". Can set username, SSH Key, SSH Agent Socket (I use multiple SSH agents), etc.
- airtonix 3y agomeh. it's much easier to have a conditional git config in ~/.gitconfig that modifies the git ssh command to explicitly use a different ssh key.
- lxe 3y agoOh this is pretty useful! Thanks!
- dtgriscom 3y agoSomething that wasn't addressed: when is the configuration read? Does this happen on every command-line git command execution? (I'm guessing "yes", but...)
- actionfromafar 3y agoThis is how git works, it's just an exe, so it must work like that I think.
- kelnos 3y agoYes. Git doesn't daemonize, so there's no way it can avoid reading its configuration every time you run a command. Ultimately what the command ends up doing likely takes orders of magnitude longer than reading and parsing the config file, so it's not really a big deal.
- de6u99er 3y agoYou can also configure multiple ssh keys through Github subdomains in your ssh conf file. While github ignores the subdomain your ssh-client will pick the corresponding ssh key bas d on the used subdomain in your repo url.
- krick 3y agoSo subdomains can be arbitrary and you just manually add them when performing git clone? Will then git push/pull/etc automatically use the fake subdomain you like for this repository?
- koolba 3y agoYou can have anything you’d like in your ssh config and it will be treated as a server name for auth and auto completion. So “work-github” can be a Host entry (with a HostName of github.com) and key A. While “play-github” would use key B.
- krick 3y agoYou are basically just repeating what he said, but it doesn't answer my question. After all I'm not ssh-ing to GitHub directly, I'd use git, which will use ssh as a transport, and I don't know if git will use the subdomains I provide the way I think it should (my primary concern being to prevent GitHub from displaying 2 public keys for a single account, so that 3rd party cannot tell that it's most probably the same person). Of course, I can test it myself, but since somebody already does that I assumed I could just ask.
- gertlex 3y agoI tested it myself, like `ssh git@rando.github.com` and that didn't work. That was my interpretation of the original comment. (reading it again, it seems like it was indeed saying what I typed below) It seems like the reply was saying instead you can do in your .ssh/config file Host work.github.com HostName github.com Host me.github.com HostName github.com (or just leave out the .github.com in the Host part) So `ssh git@me.github.com` now works... And then key the github config off of that? But I didn't try that part. So I could be wrong there.
- vanous 3y agoCan different .git-credentials files also be loaded conditionally? When one uses https access with multiple accounts....
- sp1rit 3y agoYou could probably write a custom git credential helper that does that, if it doesn't exist already.
- lathiat 3y agoDo you need multiple files? Since you can store credentials for multipl users and host combinations in the same file.
- deleted 3y ago[deleted]
- akdor1154 3y agoI use the technique in article for something similar that solves the same problem. I'll find it on pc in a sec.
- akdor1154 3y ago~/.gitconfig: [credential] credentialStore = secretservice helper = /usr/local/bin/git-credential-libsecret [credential "https://github.com"] username = akdor1154 [includeif "gitdir:~/src/mywork/"] path=~/src/mywork/.gitconfig ~/src/mywork/.gitconfig: [user] email = "12345+akdor1154-mywork@users.noreply.github.com" signingkey = ~/.ssh/id_rsa.mywork.private [credential "https://github.com"] username = akdor1154-mywork The `username` is passed to the global secret helper and is thus used for it as part of the pick/prompt context for password. I'm using the libsecret helper but this works with any.
- kentrf 3y agoDoes anyone know what is the equivalent for TortoiseGit in Windows? What path should go into gitdir if the repos are at S:\Repos\ ?
- IlliOnato 3y agoNot an equivalent, but I use "Git Extensions", and am very happy with it. I think Git on Windows uses forward slashes, but colon is retained, like this: directory = C:/Program Files (x86)/MyProject https://gitextensions.github.io https://gitextensions.github.io
- ljm 3y agoI love how the internet collectively discovers obscure git config and writes about it. I wrote this about 3 or 4 years ago detailing exactly the same: https://www.leemeichin.com/posts/conditional-git-config.html https://www.leemeichin.com/posts/conditional-git-config.html
- layer8 3y agoThis great, but not supported by all IDEs. JGit for example didn’t support includeIf last time I checked.
- HelloNurse 3y agoYou can probably still use the IDE for local operations that don't need custom configurations or server credentials, e.g. checkout, merge, commit, log, interactive visualizations of history, diff.
- layer8 3y agoThe typical use case, as in TFA, is for customizing username and email, so at least commit is already out.
- lesterzone 3y agoDo you REALLY use ~/Work/Code/Repos path? even with CDPATH configured I would use lowercase folders. I'm just a console/terminal user :D I wrote about this too https://lesterzone.github.io/blog/2023/01/10/git-work-personal.html https://lesterzone.github.io/blog/2023/01/10/git-work-person... I consider this type of 'tips' hidden gems
- chandlerswift 3y agoI'd attempted to configure this some time back, but never gotten it working, and this was the kick in the pants I needed to finally get it working! In case anyone is stuck in the same way that I was, the trailing slash at the end (which I had previously omitted, not realizing) is necessary for this to work. The docs[0] mention this, but I'd managed to repeatedly miss it: > If the pattern ends with /, * will be automatically added. For example, the pattern foo/ becomes foo/*. In other words, it matches "foo" and everything inside, recursively. [0]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-codegitdircode https://git-scm.com/docs/git-config#Documentation/git-config...
- __MatrixMan__ 3y agoInteresting, but why not just configure direnv to set appropriate env vars based on your current directory? That works for more than just git.
- kelnos 3y agoI prefer the method used in the article. All the settings are neatly kept in a git configuration file, and I don't have to track down where direnv keeps them, or remember that I need a separate tool in order to make it work. Also this allows you to set git config options that don't have a corresponding environment variable.
- xyst 3y agoI use this for contributing between multiple OSS projects. For Google projects I use a specific e-mail and sign all commits with it.
- joshbode 3y agoAnother trick I find useful for managing Git over SSH for multiple accounts (especially with bitbucket.org, which supports specifying different usernames) is the "Match exec" directive which allows you to include a shell (bash) conditional (such as a directory-check), e.g. Match originalhost bitbucket.org exec "[[ ${PWD}/ == ${HOME}/repos/work/* ]]" IdentityFile ~/.ssh/keys/work User me-work Match originalhost bitbucket.org exec "[[ ${PWD}/ == ${HOME}/repos/personal/* ]]" IdentityFile ~/.ssh/keys/personal User me
- dig1 3y agoNice trick! I'd usually set alias in ~/.ssh/config and set origin to match that alias, e.g. Host project-foo Hostname github.com User git IdentityFile ~/.ssh/some_key Then I'll pull the project with: git clone project-foo:/Foo/project.git
- crabbone 3y agoWhat's the reason to want SSH over HTTPS for Git? Genuinely curios. After HTTPS became supported I never looked back. The whole authentication management and Git remote URL syntax are a huge mess I'd never want to touch unless forced to. HTTPS makes it a lot simpler... at least for me. Am I missing something?
- Joker_vD 3y agoI personally never managed to make pushes work over HTTPS, while with SSH it works the moment clone/pull works. Plus I vaguely remember that setting up HTTP auth was way more cumbersome that SSH auth.
- crabbone 3y agoAre you talking about server-side configuration or client-side? I haven't had to set up Git server in a very long time. I'm not even sure if I had to set up HTTPS authentication for it. But, I can see how this may be potentially more difficult as you'd already have SSH set up for accessing the server by the time you get to set up Git. It's been a lot easier on the client-side though. Especially having to deal with multiple users / multiple servers and having to share configuration between different machines. Usually it just boils down to having ~/.git-credentials and if necessary, adding a similar file in the root of the repo.
- wscourge 3y agoOther than different personal/work email and username, which config do you set differently?
- brantonb 3y agoI didn't want to have to organize my work and personal repos using a directory structure, so I use matching on the remote instead. Since my job uses a GitHub organization, I'm able to conditionally include a config file that uses my work email in any GitHub repo under that organization. I wrote it up here, if that sounds useful: https://www.brantonboehm.com/code/conditional-git-config/ https://www.brantonboehm.com/code/conditional-git-config/
- thekashifmalik 3y agoThis is just what I need.
- mattmezza 3y agoI think this might be more interesting than the directory structure way. For years I've had the same setup of OP, but now that I think about it, this might make more sense for me. Will give a look.
- cglong 3y agoSurprised no one has mentioned chezmoi[1], which takes parameterization of configs to its awesome, extreme conclusion[2]. [1]: https://chezmoi.io/ https://chezmoi.io/ [2]: https://github.com/cglong/dotfiles/blob/ea33143679e936f4043a3963cda9741103632bdd/home/dot_gitconfig.tmpl https://github.com/cglong/dotfiles/blob/ea33143679e936f4043a...
- Gee8r9 3y agoI use virtual machines for development.
- Gee8r9 3y agoWhy downvotes? It is the most effective way to separate config. If any of those "condition" fails, you may nuke or compromise your repo!
- quectophoton 3y ago> Why downvotes? It is the most effective way to separate config. If any of those "condition" fails, you may nuke or compromise your repo! Maybe it was unusual enough that it didn't sound like a serious response (?), but you're completely right that the article's suggested solution can easily leak stuff by accident if you want to absolutely avoid committing with the wrong identity, thus revealing name, email, timezone, or some other metadata, in a repository where you don't want to. If I contribute to a legal-gray-area anime fansub I don't want those people (other contributors) to know anything about my IRL identity, for example, so of course I'd reduce the possibility of info leaks due to typos or because my muscle memory betrayed me. Like I mentioned in a sibling reply, I'd rather use a completely different OS user[1], a Docker container, or a different host. [1]: That's literally what they are for.
- Gee8r9 3y ago[dead]
- quectophoton 3y agoI do something similar, depending on the project and the identity I have to use. For local Linux projects, I have Docker images for my development environments, one per identity. So I keep my PC as minimal as I can, while the compilers, interpreters, etc, are only installed within a Docker image. Then I go to a project's directory, run a helper command like `identity1-workspace`, and it (1) starts the Docker container for `identity1`, (2) mounts the current directory to `/workspace` within the container, and (3) also mounts some cache directories, etc. For other hosts where I don't want to use Docker (e.g. in Raspberry Pis, or in VPS) I just have multiple users and SSH into the one I want to use. I can do this because I just use nvim and the terminal for everything, so for me there's basically no difference between developing "natively" vs developing inside a Docker container vs developing through SSH. The only difference is whether I run the command `nvim` vs `identity1-workspace` vs `ssh identity1`[1], respectively. All this sounds like too much work, but I'd rather use (1) Docker, or (2) `adduser` and `ssh`, because those I can do from memory and can trust to be reliable since `identity1` can't push to repos of `identity2` even by accident. In comparison, the article's `includeIf` looks like something that could easily leak an identity by accident, not to mention that I'd forget its syntax after 2 days. [1]: Well in this case also have to then `cd somewhere ; nvim` because writing a helper for this is no big deal.
- nektro 3y agoI only do work stuff on the work laptop so the git config is entirely separate from my personal one since its on a totally separate machine
- tomosterlund 3y agoAmazing! This is so helpful for anyone building open source, wanting to avoid committing with the work email by mistake. Thanks