Multi-Account GitHub Without Losing Your Mind: Personal, Work, and Client Repos in One Place
I have three GitHub accounts.
One personal, where my side projects live. One work, where my day job pushes commits. One client, opened last summer when a contract required me to commit from a separate identity for IP reasons.
Every one of those accounts has activity that matters. Every one of them produces commits I want to see. And for a long time, my workflow for tracking what I was actually building looked like this: open three tabs to three github.com profiles, scroll, sigh, close them, forget what I was doing.
If you have ever pushed to the wrong remote, opened a PR from the wrong account, or stared at a green commit graph wondering which account it belonged to, this is for you. Here is the system I landed on.
The three problems with multiple GitHub accounts
Multi-account GitHub does not break in obvious ways. It breaks in slow, low-grade ways that drain attention.
1. The auth problem. SSH keys, PATs, credential helpers. Every CLI tool wants to know which identity it should use. The first time you push to a personal repo from your work machine and watch your work email show up in the commit log, you start to care about this.
2. The visibility problem. GitHub does not give you a unified view across accounts. You can star repos, follow people, but the activity graph, the contributions calendar, the recent push list, those are all per-account. If your work is split across three accounts, no single page on github.com shows you what you actually did this week.
3. The context problem. When you context-switch from a client repo to a side project to a work feature branch, the cognitive cost is not just remembering the codebase. It is remembering which account you are signed into, which terminal has which SSH agent, which directory has which .gitconfig override.
I solved each one separately, and then I solved the visibility problem properly with a tool I will mention at the end.
The auth problem: per-directory git config
The classic fix, and still the best. SSH config aliases plus includeIf in ~/.gitconfig.
In ~/.ssh/config:
Host github.com-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
Host github.com-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
Host github.com-client
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_client
Then clone with the alias instead of plain git@github.com::
git clone git@github.com-personal:myname/sideproject.git
git clone git@github.com-work:org/repo.git
For the email and username, I use directory-scoped configs. In ~/.gitconfig:
[includeIf "gitdir:~/code/personal/"]
path = ~/.gitconfig-personal
[includeIf "gitdir:~/code/work/"]
path = ~/.gitconfig-work
[includeIf "gitdir:~/code/client/"]
path = ~/.gitconfig-client
Each .gitconfig-{role} file sets user.name, user.email, and user.signingkey. The trailing slash on the path matters. So does the directory layout. Every repo lives under one of three top-level folders, no exceptions. If I clone something to my Desktop or ~/Downloads/tmp, it falls back to the default identity, which I set to my personal one with a flashing-red prompt to remind me to move it.
This does not require any CLI wrapper or extension. It is just git, and once it is set up, it stays out of your way.
The visibility problem: stop opening three GitHub tabs
For a year I just opened three tabs.
github.com/personal-username, github.com/work-username, github.com/client-username. Click profile, scan recent activity, switch tab, repeat. If I wanted to see what I had pushed across all of them this week, I clicked through to each contributions calendar.
What that workflow misses is that the question I actually have is rarely "what did personal-me do." It is "what did I do." The account boundary is an artifact of how GitHub bills and authenticates, not of how my brain organizes work.
What I needed was a feed that pulled from all three accounts and showed me commits regardless of which identity made them. Plus enough metadata to recognize which side project, which client engagement, which work area each commit belonged to.
I tried a few things before settling.
A daily standup script. A bash script that ran gh api against three accounts and printed the last 24 hours of commits into a markdown file. Worked, but only ran when I remembered to run it, and the output was a wall of text I never actually read.
GitHub's REST events feed. You can pull /users/{username}/events for each account and merge them. Powerful, but you are now writing a GitHub client, and I did not want to maintain that for myself.
A self-hosted dashboard. I started building one. Got 60% there. Got bored. The repo still exists. I have not pushed to it in seven months.
The thing that finally stuck was tying the GitHub feed into the dashboard I already had open every time I opened a new browser tab.
The dashboard that already opens 40 times a day
About six months ago I started using STACKFOLO, a Chrome extension that turns the new tab into a project hub. Disclosure: I now help with the project. The reason I started using it was a different problem (the bookmarks chaos I wrote about here), but it solved the GitHub visibility problem as a side effect, and that is the part I want to talk about.
Each project in the dashboard can be linked to a GitHub repo. The extension supports multiple GitHub accounts via personal access tokens. So I added all three: personal, work, client. Each token only has read access to the repos it needs.
Now the timeline view in the new tab shows commits from all three accounts in one stream, scoped per project. If I open a new tab in the morning, I see exactly what I pushed yesterday, across every account, sorted by project, not by which login made the commit.
A few things this changed:
- I stopped opening github.com tabs to check my own activity. The new tab page already had it.
- I started recognizing real patterns. Which side project actually moves vs. which one I just say I am working on. The commit data does not lie.
-
Cross-account debugging got faster. When a side project's CI breaks because I forgot to commit a
.gitignorerule from the work repo template, I see both repos' recent commits next to each other instead of context-switching tabs.
For private repos, you do need the extension's Pro plan because that requires a stored token with private scope. Public repos work on the free tier with a token that has public_repo only. I used the free tier for two months before upgrading.
If you want to try it, the extension is on the Chrome Web Store. The multi-account GitHub setup is in the GitHub settings page after you install. You add tokens one per account and tag them with a label.
The context problem: directory-anchored mental models
The last piece was harder because it was not about tools. It was about how I think about the work.
Before, my mental model was account-shaped. "Today I am personal-me working on side projects." Then "now I am work-me working on the day job." Switching meant changing posture.
After, my mental model is project-shaped. "Today I am working on Project A, Project B, and a small client task." Each one happens to live under a different account, but the account is a routing detail. The thing I am building is the project.
That sounds obvious in retrospect. It was not obvious when I had three browser tabs open trying to figure out where last Tuesday's work went.
Two practical habits that came out of this shift:
Name directories after projects, not accounts.
~/code/personal/cli-tool/, not~/code/personal/sideproj-cli. The "personal" in the path is the auth boundary. The project name is the work boundary. Keep them separate in your head and in your shell history.Tag commits with project context, not account context. When I write a commit message, I never write "personal commit" or "work commit." I write what changed. The account is metadata, not narrative.
The system, summarized
If you are setting this up from scratch:
- Per-directory
.gitconfigwithincludeIfrules. One identity per top-level folder. - SSH config aliases per account. Clone with the alias, never with plain
git@github.com:. - A unified view of commits across accounts. Whether you build a script, use a dashboard, or roll your own, the goal is one place to see what you actually did, regardless of which login produced it.
- Project-shaped, not account-shaped, mental model. The account is auth plumbing. The project is the work.
Three accounts is not a problem to solve once. It is a workflow to maintain. The goal is to make the maintenance cheap enough that you stop noticing.
Want to try the new-tab approach? STACKFOLO turns Chrome's new tab into a project hub with multi-account GitHub support, project timelines, and per-project task tracking. Free on Chrome Web Store →
Top comments (1)
Nice collection to tips and tricks! I’ll have to see what I can use.
I use “gh” as host alias in my ssh config. So I can do “git clone gh:fyliu/peopledepot” to clone my project. In your case, you can shorten yours to gh-work, gh-personal, gh-client, if you want to save a little typing.
I also name “upstream” remotes according to the organization so I don’t accidentally push to the wrong one. Like if I intend to push to “hackforla”, I call “git push hackforla” rather than the default “upstream”. If I’m in the wrong project, it won’t have that remote and the push fails.