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>
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,
Developeris a special directory with a unique icon, making it appropriate for my usage.
Within the top-level directory, create a subdirectory named
github. This indicates that everything inside mirrors GitHub, and allows you to use the
Developerdirectory 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-workdirectory for each site.
<GitHub org / username>
Each GitHub org/user should have their own directory within the
<GitHub repo name>
The repository clone should be in a subdirectory named after the repository.
Your own repository
For your own repo, simply clone it to the appropriate directory:
git clone firstname.lastname@example.org:my-user/my-repo.git ~/Developer/github/my-user/my-repo
~/Developer/github/my-user/doesn’t exist yet,
git clonewill automatically create it for you.
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
git clone email@example.com:my-fork/next.js.git ~/Developer/github/vercel/next.js
This ensures that your clone has the correct
originremote set up for pushing.
Add the upstream remote as
up(short for “upstream”):Terminal
git remote add up firstname.lastname@example.org:vercel/next.js.git
originwill point to your fork, and
upwill point to the original repo.
You can pull in the latest changes from
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:
- 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.
- Quickly locate any repository due to the familiar organization.
grepacross 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:
# My default profile [user] name = Hiroki Osame email = email@example.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 = firstname.lastname@example.org
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!