How to organize your GitHub repository clones locally
As a software engineer, cloning repositories using Git is a common task. But without a scalable system, your local clones can quickly get disorganized—think collisions from cloning repos with the same name, or a cluttered projects
folder with repos from different owners and scopes.
Solution: The GitHub Tree structure
The GitHub Tree structure is a simple yet effective way to organize your repositories by mirroring GitHub. It helps establish a clear structure that scales as your collection grows.
Here’s a quick example of what the hierarchy might like on your machine:
~/Developer
└── github
└── <GitHub org / username>
└── <GitHub repo name>
~/Developer
: Your main coding directory (or swap it for whatever path you like).Tip
macOS gives
Developer
a special icon, which is a neat bonus.github
: A folder to reflect GitHub’s layout.This is useful in case you use ever use other platforms like GitLab, Bitbucket, etc. In my case, we had a private GitHub Enterprise server at work, so I had a
github
andgithub-work
directory.<GitHub org / username>
: A subfolder for each organization or username.<GitHub repo name>
: Where the cloned repo lives.
Cloning repositories
To clone a repo you own, run this command with the target path:
git clone git@github.com:my-user/my-repo.git ~/Developer/github/my-user/my-repo
Tip
If the ~/Developer/github/my-user/
folder doesn’t exist yet, git clone
will create it automatically.
Forked repositories
For repos you’ve forked, keep things tidy by cloning them into the original organization’s namespace:
Fork the repo on GitHub.
Clone your fork into the original org’s directory.
For example, if you forked
vercel/next.js
, clone it like this:git clone git@github.com:my-fork/next.js.git ~/Developer/github/vercel/next.js
Add the upstream remote.
Connect to the original repo (call it
up
for “upstream”):git remote add up git@github.com:vercel/next.js.git
Sync with the original whenever needed:
git pull up <branch-name>
This points origin
to your fork, and up
to the original repo.
Speed things up with a zsh function
Want to clone faster? Add this handy function to your .zshrc
:
gclone() {
if [[ -z "$1" ]]; then
echo "Usage: gclone <github-repo-url>"
return 1
fi
local repo_url="$1"
local stripped="${repo_url##*github.com[:/]}"
stripped="${stripped%/}"
if [[ "$stripped" != */* ]]; then
echo "Invalid GitHub URL: $repo_url"
return 1
fi
local clone_path=~/Developer/github/"${stripped%%/*}"/"${stripped#*/}"
clone_path="${clone_path%.git}"
git clone "$repo_url" "$clone_path" && cd "$clone_path"
}
Use it like this:
gclone git@github.com:organization/repository.git
It’ll clone the repo to ~/Developer/github/organization/repository
and take you right there.
Warning
The upstream remote isn’t automatically added because there’s no way to infer the original repo.
Benefits of GitHub Tree
By organizing your repositories with the GitHub Tree structure, you’ll enjoy several benefits:
Mirrors GitHub’s layout
- You don’t have to think about how to organize your clones; you’re simply following GitHub’s structure.
- Avoid name collisions as GitHub ensures unique repository names within an org.
Finding repos is easy
- The structure is familiar, so you can locate repos fast.
- Easily
grep
across multiple repositories with the results clearly indicating repository paths.
Scoped Git configs
If you juggle personal and work projects with different Git identities (e.g., emails), this setup simplifies configuration.
Here’s an example of a ~/.gitconfig
config toggling three different profiles based on the org:
# Default (personal)
[user]
name = Hiroki Osame
email = personal@email.com
# Work org A
[includeIf "gitdir:~/Developer/github/org-a/"]
path = ~/Developer/github/org-a/.gitconfig
# Work org B
[includeIf "gitdir:~/Developer/github/org-b/"]
path = ~/Developer/github/org-b/.gitconfig
Then, in each org directory, create the profile (e.g., ~/Developer/github/org-a/.gitconfig
):
[user]
name = Hiroki Osame
email = work@email.com
Now, whenever you commit in your personal repositories, Git will use your personal email. And when you commit to repos in your work org, it will use your work email.
Give it a spin!
That’s it! The GitHub Tree structure gets you organized fast with a system that’s intuitive and grows with you. Try it out, and if you’ve got feedback or tweaks, I’d love to hear them!