16

If I understand forking, it conceptually involves the following steps:

  1. Mirror-clone the source repo to a target repo
  2. Set an "upstream" remote on the target repo, pointing to the source repo
  3. Some other stuff, like email subscriptions, etc. (not important for this question)

This is how it looks like:

Original <──upstream─── Forked
(server)               (server)
                           ↑
                           │origin
                           │
                        (local)

The key difference from cloning is that these steps are server-side, not local. How do I replicate this manually, on the git command line?

Here's what I've done so far:

  1. Clone the source repo to a local repo
  2. Change the "origin" remote to point to the intended target repo
  3. Add an "upstream" remote pointing to the source repo

At this stage, I have everything set up on the local repo. I can sync changes between the original and forked repos using an intermediate local clone. So this is what I have:

Original                Forked
(server)               (server)
    ↑                      ↑
    │                      │origin
    │                      │
    └───────upstream─── (local)

Now how do I push this link to the server i.e. make the original repo an upstream remote of the server-side forked repo, to match the first diagram?

Note that this question is not GitHub-specific - I might also want to do this with BitBucket. Ideally, I should be able to do this across sites as well. I've read lots of similar questions here on SO, but there's no clear answer.

metacubed
  • 5,951
  • 5
  • 28
  • 57

4 Answers4

10

You can fork a project on Bitbucket using their API on command line, but you need at least read access to source project.

Syntax is:

curl -v --user {username}:"{password}" \
https://bitbucket.org/api/1.0/repositories/{accountname}/{repo_slug}/fork \
--data "name=mynewrepo"

e.g.

  1. To fork a project projectABC from an account ABC to your account XYZ with the name ProjectXYZ, use the following command

    curl -v --user XYZ:"XYZPASSWORDXYZ" \
    https://bitbucket.org/api/1.0/repositories/ABC/ProjectABC/fork \
    --data "name=ProjectXYZ"
    

    see Bitbucket documentation for more details.

  2. Now clone this project on your local machine,

    git clone your_target_git_repository_path
    
  3. Go to your project directory and add remote upstream which will point to the source repository,

    git remote add upstream source_git_repository_path
    
  4. Now, at anytime to pull the changes from source repository (say from master branch), use:

    git pull upstream master
    

    and to push your local commits to your target repository on server, use: git push origin master

  5. And when your changes on target repository are ready to be merged with the source repository, create a Pull Request either from Bitbucket website or using Bitbucket API: Pull Request

Nikhil Supekar
  • 587
  • 4
  • 16
  • Is there a way to do this cross-site, such as forking a Bitbucket repo to GitHub? – metacubed Jan 03 '15 at 07:54
  • check [Forking from GitHub to Bitbucket](http://stackoverflow.com/a/8463882) but on contrary I also found a nice tutorial on [github gist](https://gist.github.com/jcaraballo/1982605) – Nikhil Supekar Jan 03 '15 at 08:13
  • Those are all local-based methods - the sync is done using an intermediate local clone, as shown in my second diagram. I'm looking for a server-side solution. – metacubed Jan 03 '15 at 08:19
  • 2
    as you know, forks are tracked by Github or Bitbucket database on their own servers. So, if you clone a repository from one server to another it won't be considered as fork. – Nikhil Supekar Jan 03 '15 at 10:40
5

For GitHub, apparently you can now do this with the hub CLI with the command hub fork. I haven't used it, but based on the docs it looks like you would do this:

git clone git@github.com:some_user_or_organization/some_project.git
cd some_project
hub fork

...and you would end up with two remotes: origin pointing to the upstream, and one with the same name as your GitHub username pointing at your new fork. (Would be nice if hub also switched the remote names to be "upstream" and "origin", respectively, but I don't think it does.)

drammock
  • 1,925
  • 24
  • 34
1

When you push to your fork, try this option: --mirror

https://git-scm.com/docs/git-push#git-push---mirror

This might mean that you need to specify the --mirror option upon cloning as well to get the remotes to your local repo.

Alternatively you can include a remote setup script in your repo and reference it in the developer setup manual of your project.

Will
  • 118
  • 1
  • 9
0

The steps to create a local copy of the repo - pointing to the final forked repo are as you you have detailed.

The next step would be to create the forked repo. It can be done from command line using Github API - not git; see https://stackoverflow.com/a/2425632/429758 for more info.

After that, it is a straightforward git push origin master to complete the manual forking.

Note: Bitbucket too provides a REST API which allows for creating the forked repo from command line.

Community
  • 1
  • 1
Prakash Murthy
  • 12,355
  • 3
  • 38
  • 66