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
originwhich 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 pullcommand and also to sync your local changes to the remote repository when you do a
If you fork a project and want to use the
forking workflowtechnique 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
forkcommand 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
originto 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.
- 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
originremotes 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!