A convention for organizing your GitHub repository clones
As a software engineer, cloning repositories using Git is a common task. Most devs just create a single projects
directory and clone all repositories there. However, this approach does not scale well and can lead to organizational issues like name collisions and difficulty finding repositories.
Solution: The GitHub Tree structure
The GitHub Tree structure is a straightforward yet effective way to organize your repositories by mirroring the organization on GitHub. It helps establish a clear structure that scales as your collection grows.
The structure is as follows:
~/Developer
└── github
└── <GitHub org / username>
└── <GitHub repo name>
~/Developer
Choose a top-level directory for all your coding-related activities.
While I use
~/Developer
, feel free to use a different path of your preference. On macOS,Developer
is a special directory with a unique icon, making it appropriate for my usage.github
Within the top-level directory, create a subdirectory named
github
. This indicates that everything inside mirrors GitHub, and allows you to use theDeveloper
directory for other things.This is useful if you use other Git servers like GitHub Enterprise, GitLab, or Bitbucket. In my case, I used to use a private GitHub Enterprise server at work, so I had a
github
andgithub-work
directory for each site.<GitHub org / username>
Each GitHub org/user should have their own directory within the
github
directory.<GitHub repo name>
The repository clone should be in a subdirectory named after the repository.
Cloning repositories
Your own repository
For your own repo, simply clone it to the appropriate directory:
git clone git@github.com:my-user/my-repo.git ~/Developer/github/my-user/my-repo
Tip
If ~/Developer/github/my-user/
doesn’t exist yet, git clone
will automatically create it for you.
Forked repository
When cloning forks, use the original namespace:
Fork the repository on GitHub.
Clone the forked version to the directory of the original org.
For example, if contributing to
vercel/next.js
, clonemy-fork/next.js
to~/Developer/github/vercel/next.js
:git clone git@github.com:my-fork/next.js.git ~/Developer/github/vercel/next.js
This ensures that your clone has the correct
origin
remote set up for pushing.Add the upstream remote as
up
(short for “upstream”):git remote add up git@github.com:vercel/next.js.git
This way
origin
will point to your fork, andup
will point to the original repo.You can pull in the latest changes from
up
:git pull up <branch-name>
This approach helps maintain a clear separation between your repos and forks.
Benefits of the GitHub Tree
By organizing your repositories with the GitHub Tree structure, you’ll enjoy several benefits:
GitHub mirror
- You don’t have to think about how to organize your repositories; you’re simply following GitHub’s structure.
- Avoid name collisions as GitHub ensures unique repository names within an org.
Finding code
- Quickly locate any repository due to the familiar organization.
- Easily
grep
across multiple repositories with the results clearly indicating repository paths.
Scoped Git configurations
If you’re a dev with both personal and work projects in the same environment, you may want to commit using your work email for repositories in the work org.
This setup allows you can configure this seamlessly in your top-level ~/.gitconfig
by toggling the appropriate Git profile based on which directory you’re in.
Here’s an example of how to set up three different profiles based on the org:
~/.gitconfig
:
# My default profile
[user]
name = Hiroki Osame
email = personal@email.com
# My profile for Org A
[includeIf "gitdir:~/Developer/github/org-a/"]
path = ~/Developer/github/org-a/.gitconfig
# My profile for Org B
[includeIf "gitdir:~/Developer/github/org-b/"]
path = ~/Developer/github/org-b/.gitconfig
Note, the above explicitly references a .gitconfig
file in each org directory. To set this up, create a .gitconfig
with the relevant configuration:
[user]
name = Hiroki Osame
email = email@company.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.
By setting up different configs for each org, you can easily switch between your personal and work-related projects, ensuring that your commits and contributions are associated with the correct identity.
Try it out!
Using the GitHub Tree structure for organizing repository clones can greatly streamline your workflow as a software engineer. It ensures a clear and scalable organization, eliminates name collisions, and simplifies finding repositories.
Give it a try, and let me know what you think!