Use multiple accounts with git

2024-11-30

Welcome to the legendary one-guide-to-rule-them-all for managing multiple GitHub accounts on Windows. This guide assumes you need to maintain at least two GitHub accounts (e.g., personal and work), each with separate SSH keys and proper Git identity configuration in tools like VS Code. Alrighty then!

With this guide, you can "easily":

  • Maintain multiple SSH keys side by side.
  • Use distinct aliases in your SSH config file.
  • Automatically choose the correct identity for pushes via local Git config or conditional includes.
  • Avoid accidental overwrites and clone mistakes.

Text-Based Flowchart for Quick Reference

┌────────────────────────────────────────────────┐
│                START HERE                      │
└────────────────────────────────────────────────┘
                ▼
┌────────────────────────────────────────────────┐
│ A) Do you have existing SSH keys?             │
│     Yes -> Step 0,1: Backup Keys              │
│     No  -> Step 2: Generate New Keys          │
└────────────────────────────────────────────────┘
                ▼
┌────────────────────────────────────────────────┐
│ Step 3: Update/Create SSH config              │
│   (Map each alias to a specific private key)   │
└────────────────────────────────────────────────┘
                ▼
┌────────────────────────────────────────────────┐
│ Step 4: Add Public Keys to Each GitHub Account │
└────────────────────────────────────────────────┘
                ▼
┌────────────────────────────────────────────────┐
│ Step 5: Test the SSH Connection               │
│   (ssh -T git@github-alias)                   │
└────────────────────────────────────────────────┘
                ▼
┌────────────────────────────────────────────────┐
│ Step 6: Naive Cloning Pitfall? Use alias!      │
│   (git@github-alias:...)                       │
└────────────────────────────────────────────────┘
                ▼
┌────────────────────────────────────────────────┐
│ Step 7: Set or Update Repository Remotes       │
│   (git remote set-url ... git@github-alias:...)│
└────────────────────────────────────────────────┘
                ▼
┌────────────────────────────────────────────────┐
│ Step 8: Configure Git Identities               │
│   (Per-repo or conditional includes)           │
└────────────────────────────────────────────────┘
                ▼
┌────────────────────────────────────────────────┐
│   DONE! Troubleshoot if necessary             │
└────────────────────────────────────────────────┘

0. Preliminary Check: Detect Existing SSH Keys, map Associated Accounts, label relevant files

1. Preliminary Check: Do You Already Have SSH Keys?

  1. Open a Command Prompt or PowerShell and navigate to your SSH folder:

    cd %userprofile%\.ssh
    

    🔹 If this fails with something like The system cannot find the path specified, it simply means the .ssh directory doesn't exist yet — likely because you've never generated an SSH key.

    👉 In that case, create the folder manually:

    mkdir %userprofile%\.ssh
    cd %userprofile%\.ssh
    
  2. List the existing files:

    dir
    
  3. Look for files like:

    • id_ed25519 and id_ed25519.pub
    • id_rsa and id_rsa.pub
    • Any custom-named keys (e.g., id_ed25519_work, id_ed25519_personal).
  • If you do not find any existing SSH keys, skip to Step 2.
  • If you do see id_ed25519 and id_ed25519.pub (or other key files), proceed with Step 1.

2. Extract Account Information from Public Keys

  1. For each .pub file, display its contents:

    type id_ed25519.pub
    
    • The public key will look like this:

      ssh-ed25519 AAAAC3...base64-encoded-key... user@example.com
      
    • Note the email or username at the end (e.g., user@example.com). This often corresponds to the associated GitHub/Gitlab account.

  2. Document your findings in a table (manually or mentally):

    Key Name Associated Account/Email Associated Git Account Git-Server Notes
    id_ed25519 user@example.com - - private project A,B and C
    id_ed25519_work work-email@example.com - - for code reviews at MegaCorp

3. Test Each Key with GitHub

  1. Use the following command to test the key directly with GitHub:

    ssh -i id_ed25519 -T git@github.com
    
  2. If using another Git server (e.g., GitLab), modify the command:

    ssh -i id_ed25519 -T git@gitlab.example-company.com
    
    • Replace id_ed25519 with the private key name.

    • GitHub will respond with a message if the key is registered:

      Hi username! You've successfully authenticated, but GitHub does not provide shell access.
      
    • Note the username returned by GitHub.

  3. Repeat for all private keys:

    ssh -i id_ed25519_work -T git@github.com
    
  4. Fill the new info into summary of detected keys, associated accounts, and their purpose:

    Key Name Associated Account/Email Associated Git Account Git-Server Notes
    id_ed25519 user@example.com krausality Github private project A,B and C
    id_ed25519_work work-email@example.com loremipsum Github for code reviews at MegaCorp
  • If a key does not return a valid response from GitHub, it might not be registered. Plan to either register the key or generate a new one for the intended account.

1. Back Up Existing Keys

Purpose: Safeguard current keys so you can keep using them for your first GitHub account without losing access.

  1. In the .ssh folder, rename your existing keys:

    ren id_ed25519 id_ed25519_krausality
    ren id_ed25519.pub id_ed25519_krausality.pub
    

    or manually via

    explorer.exe .
    

    Replace id_ed25519_krausality with a name that matches your account if desired (e.g., id_ed25519_personal).

  2. Confirm the files were renamed properly:

    dir
    
  3. These renamed keys are now dedicated to the first account (example: github-krausality).

Note: If you do not have existing keys, skip this entire step and move on.


2. Generate New SSH Keys

Purpose: Create additional SSH key pairs—one per GitHub account.

  1. Open a Command Prompt or PowerShell in your .ssh folder:

    cd %userprofile%\.ssh
    
  2. Generate a new Ed25519 key:

    ssh-keygen -t ed25519 -C "email-for-second-account@example.com" -f "%userprofile%\.ssh\id_ed25519_loremipsum"
    
    • -C adds a comment (your email).
    • -f specifies the output filename (id_ed25519_loremipsum) so it doesn’t overwrite any existing key.
    • Choose to add a passphrase (for extra security) or press enter twice to leave it blank.

Repeat this step for any additional GitHub accounts you need. Each key must have a unique filename.


3. Configure Your SSH config File

Purpose: Instruct SSH to pick the correct private key based on a “Host alias.”

  1. Create or open the SSH config file in Notepad:

    notepad "%userprofile%\.ssh\config"
    
  2. Add (or modify) entries for each account. For example:

    # krausality account
    Host github-krausality
        HostName github.com
        User git
        IdentityFile C:/Users/YOUR_USERNAME/.ssh/id_ed25519_krausality
        IdentitiesOnly yes
    
    # loremipsum account
    Host github-loremipsum
        HostName github.com
        User git
        IdentityFile C:/Users/YOUR_USERNAME/.ssh/id_ed25519_loremipsum
        IdentitiesOnly yes
    
    • Replace C:/Users/YOUR_USERNAME with your actual Windows user profile path.

    • If you renamed your first key differently, reflect that name here.

      Q: Can the IdentityFile path in the SSH config file be relative? A: Use ~/.ssh/ for shorthand; absolute paths are required otherwise.

      IdentityFile ~/.ssh/id_ed25519_krausality
      
  3. Save the file. Ensure it is named exactly config (no .txt extension). If unsure how, use:

    ren "%userprofile%\.ssh\config.txt" config
    

4. Add Public Keys to Each GitHub Account

  1. Obtain the public key content (example for krausality):

    type "%userprofile%\.ssh\id_ed25519_krausality.pub"
    

    Copy everything shown (including ssh-ed25519 at the start).

  2. Log in to the corresponding GitHub account:

    • Go to Settings > SSH and GPG keys.
    • Click New SSH key.
    • Paste the public key.
  3. Repeat for the second account (loremipsum), copying and pasting:

    type "%userprofile%\.ssh\id_ed25519_loremipsum.pub"
    

5. Test Your Setup

  1. SSH Test each alias:

    ssh -T git@github-krausality
    ssh -T git@github-loremipsum
    
  2. If everything is correct, you’ll see a message like:

    Hi YOUR_USERNAME! You've successfully authenticated, but GitHub does not provide shell access.
    

6. Avoid the “Naive Cloning” Pitfall

  • A standard GitHub clone command (e.g., git clone git@github.com:USERNAME/REPOSITORY.git) ignores your alias because it references github.com, not your custom alias like github-loremipsum.

  • Solution: Use your configured alias in the clone URL:

    git clone git@github-loremipsum:USERNAME/REPOSITORY.git
    
  • Suppose we want to clone the imaginary "idea2exe" repository owned by an imaginary GitHub user called "wittycoder". The URL of the repository would be:

    https://github.com/wittycoder/idea2exe.git
    
  • To clone this repository using the loremipsum GitHub account, the assembled clone command would be:

    git clone git@github-loremipsum:wittycoder/idea2exe.git
    
  • Using the custom alias ensures that the correct SSH key is picked up.


7. Set or Update Repository Remotes

Purpose: Ensure each local repository uses the alias (e.g., github-krausality) so the correct key is used.

  1. Navigate to your local repository folder:

    cd C:\path\to\my-repo
    
  2. Check current remote URLs:

    git remote -v
    
  3. If needed, update the remote:

    git remote set-url origin git@github-krausality:USERNAME/REPOSITORY.git
    
  4. Repeat for the other account’s repositories:

    git remote set-url origin git@github-loremipsum:USERNAME/REPOSITORY.git
    

Remember to replace USERNAME and REPOSITORY accordingly (See step 6), and use the correct alias (github-krausality or github-loremipsum).


8. Configure Git Identity (name/email) for Each Repository

If you use VS Code or otherwise commit under multiple identities, you must also configure Git user information to match the account.

Option A: Per-Repository

  1. In your repository folder:

    git config user.name "Your Name Here"
    git config user.email "email@domain.com"
    
  2. Verify:

    git config --list
    

    Look for user.name and user.email in the local scope.

Option B: Conditional Includes in Global .gitconfig

  1. Open your global config:

    notepad "%userprofile%\.gitconfig"
    
  2. Add lines like:

    [includeIf "gitdir:C:/Users/YOUR_USERNAME/GitHub/krausality/"]
        path = C:/Users/YOUR_USERNAME/.gitconfig-krausality
    
    [includeIf "gitdir:C:/Users/YOUR_USERNAME/GitHub/loremipsum/"]
        path = C:/Users/YOUR_USERNAME/.gitconfig-loremipsum
    
    • Use paths to each local repository folder or a parent directory.
  3. Create the specific config files, for example:

    notepad C:/Users/YOUR_USERNAME/.gitconfig-krausality
    

    Then add:

    [user]
        name = KRAUSALITY_USER
        email = krausality@example.com
    

    Repeat for .gitconfig-loremipsum with the second account’s details.

Option C: Global Default + Local Override for Exceptions

Use this if you mostly commit with one identity but occasionally use another.

  1. Set your main identity globally (used by default everywhere):

    git config --global user.name "Main Name"
    git config --global user.email "main@example.com"
    
  2. Override only in specific repos where you use another identity:

    cd path/to/other-repo
    git config user.name "Other Name"
    git config user.email "other@example.com"
    

This keeps your setup simple while ensuring proper attribution for all projects.


9. Troubleshooting Tips

  • Verbose SSH: If cloning fails and you’re unsure which key is being used, run:

    GIT_SSH_COMMAND="ssh -v" git clone git@github-loremipsum:USERNAME/PROJECT.git
    

    Inspect the logs for the identity file path.

  • Force Specific Key:

    GIT_SSH_COMMAND="ssh -i C:/Users/YOUR_USERNAME/.ssh/id_ed25519_loremipsum" git clone git@github.com:USERNAME/PROJECT.git
    

    This bypasses any misconfiguration temporarily.

  • VS Code: If commits push under the wrong account, double-check:

    1. The local repository’s user.name / user.email.
    2. The remote URL uses the correct alias.
    3. Restart VS Code to clear any caching.

Final Words

You now have completed the “one-guide-to-rule-them-all” for Windows-based multi-Git-account management. If you encounter unexpected issues or have further questions, revisit each step in the flowchart or consult the troubleshooting section. Good luck, and happy coding!