Help! I want to fork my own repo (sort-of). Should I use a Github Template Repo or manual steps?

Posted by

For one of my learning projects, I recently wanted to deviate significantly from my existing GitHub project repository, but didn’t want to have these in their own branch as it may evolve into its own entire line of thinking and development and didn’t necessarily need to keep track or want to integrate any of the source project repository’s newer updates to its main branch or contribute these changes back to the main project.

This was a different use case than that for projects I had forked from other GitHub users which were always meant to remain strongly tied to the original repository and were as simple as clicking the Fork button in the top right of the project’s GitHub page as shown in the menu below.

Feature branching would be the way to go here if testing something new for my own repo so GitHub didn’t provide a “native” way of forking a repository in my own personal repository back into a new repo in that same user account, unless the destination repository is part of an organisational account’s listing as shown in the screenshot below.

Because in this case this is potentially an entirely new project and not just a feature, this could be a candidate for the GitHub Template repository option and exploring that feature. GitHub does a great job distinguishing between the differences between forking and templating behaviors on its platform

Creating a repository from a template is similar to forking a repository, but there are important differences:

A new fork includes the entire commit history of the parent repository, while a repository created from a template starts with a single commit.

Commits to a fork don’t appear in your contributions graph, while commits to a repository created from a template do appear in your contribution graph.

A fork can be a temporary way to contribute code to an existing project, while creating a repository from a template starts a new project quickly.

https://docs.github.com/en/free-pro-team@latest/github/creating-cloning-and-archiving-repositories/creating-a-repository-from-a-template

So this seemed like a good option to me, but I also wanted to keep one benefit of a fork, which is the ability to sync my main branch with the latest main branch in the source repo by having an upstream remote and using git merge upstream/main when appropriate to pull those changes into my forked project until this new project was ready to stand and evolve on its own. I also thought learning some of the steps to achieve my goal in a less automated manner would give me an appreciation for this feature when I looked to solve this problem again in future.

Before we get to the solution, some background for those not so familiar with how Git and GitHub work. Git uses the concepts of remotes for synchronising between your copy of a repository on a local disk and your centralised storage location. Usually with services like GitHub you always have one remote called origin which is pointing to the source URL you have cloned your local repository from. This allows you to get new commits to the remote branch you are working within using the git pull command and also to sync your local changes to the remote repository when you do a git push command.

If you fork a project and want to use the forking workflow technique you actually are adding a 2nd remote origin URL that you wish to synchronise with when changes are made to it. Git doesn’t actually have a fork command because what you are doing when you fork in GitHub is basically cloning the remote repository from the original location into your own location, and then resetting the origin to your new location. GitHub does some magic under the hood to keep track of where the original location was so if you make a change that’s particularly interesting to the original repository’s owners, you can open a PR (pull request) to start the process of having those changes integrated back to the main project.

So our manual steps will simulate what “template” repositories in GitHub are doing when you utilise them to generate a new repository within the same user account. At the end of this approach you may choose to use the forking workflow technique once more to keep in sync with changes to your source repository for some time.

Note: If you’re not starting a new project separate from your original project, feature branching is probably a better strategy here than forking if you own the repo.

  1. From the GitHub website, create your new repository with the target name you want to use. An example screenshot of this page is below

2. From your local. terminal or command prompt, clone your source repository into a new folder on your local disk that would be the intended target name of your new project. E.g. git clone https://github.com/user/sourcerepo targetrepo

3. We are now going to change the origin to point to my target repository location. From the terminal or command prompt first remove the origin remote using

git remote remove origin

And then add it back using the newly created repo’s URL

git remote add origin https://github.com/user/targetrepo

We set the upstream target for the main branch and push our cloned contents to that new repo instead

git push --set-upstream origin main

And that’s it. You can now safely experiment in what is essentially a fork of your original repo within your own account. If you wanted to keep the original repo as an upstream remote you can also do that simply with

git remote add upstream https://github.com/user/sourcerepo 

Note the caveat with this approach is there’s no ties between the upstream and origin remotes recorded within GitHub itself so pushing back changes may be a little more manual as well as the “magic” GitHub usually does to keep the association between the two projects to allow the standard fork and PR workflow to be available didn’t happen in this case. To push a change back to the source repository, you would first push these changes to a branch on the source repository and then follow the pull-request workflow in GitHub for that source repository to get the changes merged into the main branch. You may also need to cherry-pick your commits with this approach since these are now essentiall two different projects so not every change in one is applicable to the other.

I hope you found this useful, if so feel free to drop a comment below or on Twitter to me about it. Happy hacking!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.