Motivation#
It’s very common for developers to have multiple git profiles, especially when working on different projects or contributing to open source. To be honest, git does not provide a battery-included solution for this. However, there are several strategies you can use to manage multiple profiles effectively.
What makes things complicated?#
After serval years of using git, I found that here are some common scenarios that I encountered:
- Multiple identities: I want to use different identities for different projects, such as work and personal projects.
- Different SSH keys: I want to use different SSH keys for different accounts.
- Imperceptible changes: I want to make sure that my commits are always signed with the correct identity, even if I forget to set it up for a new repository.
Don’t Panic#
Luckily, git still provides some tools to help you manage multiple profiles. The key idea is to route different profiles based on the remote URL:
; here comes the shared configuration[alias] ci = commit co = checkout st = status br = branch
; this is the default profile; the fallback profiles should go first, because git will; evaluate the includes in order and NO short-circuiting[includeIf "gitdir:*"]path = ~/.gitprofiles/fallback
; assuming alice's github username is "alice"[includeIf "hasconfig:remote.*.url:https://*github.com/alice/*"]path = ~/.gitprofiles/alice-profile
[includeIf "hasconfig:remote.*.url:git@*github.com:alice/*"]path = ~/.gitprofiles/alice-profile
; assuming bob's github username is "bob"[includeIf "hasconfig:remote.*.url:https://*github.com/bob/*"]path = ~/.gitprofiles/bob-profile
[includeIf "hasconfig:remote.*.url:git@*github.com:bob/*"]path = ~/.gitprofiles/bob-profileWith this setup, git will automatically load the correct profile based on the remote URL of the repository. Next, we just need to handle the SSH keys. The most common way to do this is to use the ssh_config file:
# alice's githubHost alice.github.com # This HostName trick is for chinese users only, # since they need to use vpn to access github. # While the vpn provider usually blocks the ssh port 22 # to prevent users exploiting others' servers. HostName ssh.github.com Port 443 AddKeysToAgent yes IdentityFile ~/.ssh/github-alice
# bob's githubHost bob.github.com HostName ssh.github.com Port 443 AddKeysToAgent yes IdentityFile ~/.ssh/github-bobHowever, this is not enough, since it is perceptible. We need to tweak the remote URL of the repository to match the SSH config:
# for alice's repositorygit remote add origin alice.github.com:alice/repo.git# ^^^^^
# for bob's repositorygit remote add origin bob.github.com:bob/repo.git# ^^^Don’t worry, git provides a way to change the remote URL easily and imperceptibly:
[user] name = Alice email = alice@github.com
[url "git@alice.github.com:alice"]; ^^^^^^^^^^^^^^^^ should match the Host in ~/.ssh/config insteadOf = https://github.com/alice
[url "git@alice.github.com:alice"]; ^^^^^^^^^^^^^^^^ should match the Host in ~/.ssh/config insteadOf = git@github.com:alice[user] name = Bob email = bob@github.com
[url "git@bob.github.com:bob"]; ^^^^^^^^^^^^^^ should match the Host in ~/.ssh/config insteadOf = https://github.com/bob
[url "git@bob.github.com:bob"]; ^^^^^^^^^^^^^^ should match the Host in ~/.ssh/config insteadOf = git@github.com:bobWith this setup, git will automatically do the following routing:
git@github.com/alice/*.githttps://github.com/alice/*.git--> git@alice.github.com:alice/*.git
git@github.com/bob/*.githttps://github.com/bob/*.git--> git@bob.github.com:bob/*.gitThen ssh_config will handle the authentication seamlessly! Now, enjoy your git life with multiple profiles!