48

I want to fork a github project to fix a couple of issues and then send a pull request.

The problem I'm running into is that I've already forked the project to adapt it for another user base.

Is it possible to create a second fork? If so, how?

When I try to fork now it just takes me to the previously created fork.

pixelfairy
  • 1,479
  • 1
  • 15
  • 29
  • 5
    Why not just create a new branch from master, fix stuff and pull request that branch to the original projects master? – noMAD Jan 23 '15 at 22:28
  • 2
    The ugliest solution I can think of is to create a new GitHub account. I do not seriously suggest this. I suspect, as @noMAD suggests, that this is a job for a branch, not a fork. – Keith Thompson Jan 23 '15 at 22:39
  • 1
    @noMAD that would work since I'm a contributor. Just curious, would that solution work if I was not a contributor? – pixelfairy Jan 23 '15 at 22:50
  • @pixelfairy, what do you mean by "contributor"? If you submit a pull request, isn't that contributing by definition? – ChrisGPT was on strike Jan 24 '15 at 04:16
  • @Chris ...I mean that I could just commit and push without making a pull request, but I want to do it the offical way and I want somebody else to review the changes before I push to a public project. – pixelfairy Jan 24 '15 at 08:52

5 Answers5

21

There is no way to have two forks of the same GitHub project unless you use two different GitHub accounts.

So:

  1. Create a separate GitHub account (and verify the email)

  2. Fork the project

  3. Invite your main GitHub account as a "Collaborator" (from the settings)

You may need to add the extra step of creating an organization with the new GitHub account and inviting your main github account as an owner of the organization (also make sure your new fork is in that new organization). This will let you do things like deploy automatically to a Heroku app that is connected to your main GitHub account.

Why can't we just have multiple forks???

pixelfairy
  • 1,479
  • 1
  • 15
  • 29
7

I mean that I could just commit and push without making a pull request, but I want to do it the offical way and I want somebody else to review the changes before I push to a public project.

GitHub pull requests do not need to be submitted from a fork; they work within a single repository as well:

Pull requests are especially useful in the fork & pull model because they provide a way to notify project maintainers about changes in your fork. However, they're also useful in the shared repository model where they're used to initiate code review and general discussion about a set of changes before being merged into a mainline branch.

There's nothing stopping you from creating a pull request even if you don't technically have to. This is often considered a best practice, and GitHub's own Flow model is largely based on pull requests.

Creating a pull request within a single repository is very similar to creating one from a fork:

  1. Create a feature branch and push your work to that branch on GitHub
  2. In the GitHub web UI, switch to your feature branch
  3. Click the "Compare" & review button
ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257
  • Thanks! That's really good information. This definitely helps me with my immediate goals. ...Is the official answer that I can't create more than one fork? What will happen if I want to make a fork for another user-base? Would I need to first transfer ownership of the other (first) fork? – pixelfairy Jan 24 '15 at 17:47
  • 2
    @pixelfairy, the official answer is "sort of". As far as I know, there is no way to create another fork under your account *using the web UI's fork button*. (You may want to investigate [organizations](https://github.com/blog/674-introducing-organizations).) But when it comes down to it, a fork is just a copy of a repository. You can easily create a new empty repository, call it `project-fork`, and push to it. See http://stackoverflow.com/questions/12338240/how-can-i-fork-the-original-repo-when-ive-already-forked-a-different-fork for a more thorough answer. – ChrisGPT was on strike Jan 24 '15 at 17:54
  • I like the work-around! For the work at hand I will follow the GitHub Flow Model and then if I want to fork the codebase for a new userbase I will just create a new repo and push to it. Thanks!! – pixelfairy Jan 26 '15 at 01:53
  • 4
    Sometimes you just need two forks. – pixelfairy May 22 '17 at 23:04
  • Some times you could figure out how to do what you want with a single fork, but it is (or rather it would be) much, much, simpler to do it with two forks. – Mars Sep 26 '17 at 18:02
  • 1
    @pixelfairy You really don't. Branches are free, forks aren't. – éclairevoyant Mar 18 '23 at 06:24
3

The best way, recommended by github manual, is use command line git, mirror clone your repo and push it to your github.

https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/duplicating-a-repository

If you strongly prefer GitHub web interface to the command line, a GUI friendly workaround is create a new organization and fork to that new organization.

Another GUI way I can think of is to declare a fork as a template repo using repo's setting so you can create as many forks as you need.

Serge
  • 3,387
  • 3
  • 16
  • 34
3

The trick is not to use the master branch to create pull requests. Then you won't need to create multiple forks since you can make as many branches as you need and make pull requests against each branch independently.

Given a clean forked repo, create a dedicated branch and use that branch for the pull request.

You can create branches from the web UI (although it is not obvious).

Click the branch selection dropdown, type the new branch name in the input field, and then you'll see a clickable link Create branch: <new-branch-name> as shown below. The tricky UI part is that it might not be very obvious you should click the "create branch: xyz..." — it is NOT displayed as a button or as a hyperlink, and there is NO indication that this is a clickable link. Moreover, there is NO hint whatsoever that a branch can be created until you type in the search box — anyone would probably assume that the search box is used exclusively for searching branches, and not for creating them.

github web create branch

In case you already made changes directly in your fork's master branch then consider moving those changes into a dedicated branch and hard resetting the master branch to the original remote so that you keep it clean for synching with the upstream repo.

See also:

ccpizza
  • 28,968
  • 18
  • 162
  • 169
  • I've marked this as the answer because it sounds like the most intuitive and least amount of hassle. If somebody uses this successfully (or especially if it doesn't work) will you please comment. (I'm not going to test it since I just logged into StackOverflow on a whim and saw this... and I should be asleep already.) Thanks for the trick! – pixelfairy Apr 13 '22 at 06:57
1

You can easily accomplish your purpose by using the concept of multiple remotes.

Quick Answer

Within your repository execute the following sequence of commands:

git remote add upstream https://github.com/user_or_org_of_upstream_repo/upstream_repo
git fetch upstream
git checkout upstream/main
git checkout -b name_of_branch_you_want_to_track_in_your_repo

Make, add, and commit your edits, then push the changes to your branch back into your GitHub fork with:

git push --set-upstream origin name_of_branch_you_want_to_track_in_your_repo

The branch, completely disconnected from the other branches in your repo (other than any source tree parentage as far up the line as the most recent common ancestor), will now be available to use for a pull request in GitHub.

Voila!

Explanation

git remote add upstream https://github.com/user_or_org_of_upstream_repo/upstream_repo

adds another remote repository and labels it upstream. The label could be anything -- upstream is more or less the accepted standard name for the parent of your fork, but it could be 'bob', 'mary', 'dirt', or anything else. Also, the remote can be any repository at all, though I've only ever experimented with fetching from a repository that is at least a parallel fork of the same upstream remote.

git fetch upstream Does the work of actually getting the main and other branches of the new repository and cloning them into your local. They are just sitting there now, waiting for you to do something with them.

git checkout upstream/main Checks out the main branch of the repository you have labelled in your remotes list as 'upstream'. Of course, you could check out any other branch in the repository.

git checkout -b name_of_branch_you_want_to_track_in_your_repo Creates a local branch where your changes can be tracked.

git push --set-upstream origin name_of_branch_you_want_to_track_in_your_repo pushes your new branch back to the default remote, origin. Again, you could push the branch to any other remote for which you have write permissions.

More Explanation:

When you fork and clone your repository, the default remote repository is your fork and the label for the fork is 'origin'. The git remote command shows this -- for example this is the output of that command for a fun little repo I made to [unsuccessfully] master the online game 'Wordle'.

> git remote -v
origin  https://github.com/jameshalgren/wordle_analyst_ideas (fetch)
origin  https://github.com/jameshalgren/wordle_analyst_ideas (push)

As you work with your fork, the branches in your local repository will likely be based on the main branch within the origin repository. When you add/commit/push changes to your branches, the remote version of those same branches will be updated in your fork on GitHub. That's why you see this message the first time you try to push a new branch:

fatal: The current branch test_new_branch has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin test_new_branch

Notice the label 'origin' in the instructions. This is a hint to the power of remotes. You can actually push to any other remote repository, as long as you have appropriate permissions. In the first command, git remote, you can also see the origin label. If you forked the repository in the example above, added remote repositories for your upstream and possibly several other collaborators, the git remote command would start to look like this:

> git remote -v
origin  https://github.com/youruser/wordle_analyst_ideas (fetch)
origin  https://github.com/youruser/wordle_analyst_ideas (push)
upstream    https://github.com/jameshalgren/wordle_analyst_ideas (fetch)
upstream    https://github.com/jameshalgren/wordle_analyst_ideas (push)
collaborator    https://github.com/collaboratoruser/wordle_analyst_ideas (fetch)
collaborator    https://github.com/collaboratoruser/wordle_analyst_ideas (push)
James H.
  • 11
  • 1