How to convert a readonly git clone from github to a forked one

From time to time I encounter this issue.

Let's say that I did following to read the source code of rails because I am running into some issues.

git clone git://github.com/rails/rails.git

During the research I tested something and now I have a fix I would like rails core team to take a look at. How do I push my changes to a forked version of rails.

Remember when I cloned, I did not clone a forked version but a read-only version.

It is not that I am opposed to forking. It is just that sometimes I think I am just going to browse then I want to add something.


Solution 1:

When you clone a repo, it automatically sets up a remote called origin which refers to the repo that you have cloned. This is now pointing to the upstream Rails project, but what you need is to create your own fork that you can push to, and then set up a remote that points there so you can push to it.

The first step is to click the "Fork" button on the upstream GitHub project page (picture from GitHub instructions on forking):

GitHub fork button

Once you've done that, find and copy the URL for that repo. Make sure you use the SSH URL, which has read and write access. It should be something like [email protected]:nadal/rails.git, assuming your user name is nadal.

Now you can create the remote, which allows Git to keep track of a remote repository, pulling from it or pushing to it depending on the access you have. You can choose to either replace origin with the one that you will push to (which is how many people have it set up), or leave origin pointing to upstream and instead create a new remote. I'll show how to do the first setup; the second should be easy to figure out.

To change origin to point to your fork on GitHub, you will probably want to keep the upstream branch around somewhere, so rename it to upstream:

git remote rename origin upstream

Now create a new remote pointing to your fork:

git remote add -f origin [email protected]:nadal/rails.git

And now you should be able to push to your new fork:

git push origin master

Once you are happy with the changes you've pushed up to GitHub, and would like someone from the Rails team to look at it, you have two choices. One is to send a pull request using GitHub; see the docs there for how to do that. If you only have one or a few small patches, however, the Rails team would prefer that you create a Lighthouse ticket and attach you patch; see the instructions on contributing to Rails for more information.

edit Here's a diagram to indicate what's going on. What you have done is simply clone the upstream rails repo; so now you have your own repo on your own machine, which refers to git://github.com/rails/rails.git as origin:

Github:    git://github.com/rails/rails.git
                    ^
                    |
Remotes:          origin
                    |
Your machine:     rails/

Here's what you get if you forked and then clone your fork:

Github:    git://github.com/rails/rails.git <-- [email protected]:nadal/rails.git
                                                           ^
                                                           |
Remotes:                                                origin
                                                           |
Your machine:                                           rails/

If you follow my instructions, here is what you will get:

Github:    git://github.com/rails/rails.git <-- [email protected]:nadal/rails.git
                        ^                                  ^
                        |                                  |
Remotes:            upstream                            origin
                        |                                  |
Your machine:           \-------------------------------rails/

Which is just like the version that you get by forking, except that it also has an upstream remote so you can track official changes and merge them in to your code (if you had created the forked version, you would probably want to add the upstream remote as well).

Solution 2:

A very easy way to switch from cloned to forked mode is using the hub wrapper from http://hub.github.com/.

When this is installed, just run

hub fork

from within your read-only clone.

Solution 3:

It should not matter. You can add another remote, specifying your non-forked repo, if you so wish. Push your changes to that.