views:

351

answers:

2

In both of the following StackOverflow questions, the accepted answer describes how to merge changes from a forked repository in the situation where you fork a repo, the original repo is modified, and then you want to merge the changes made to the master branch back into your forked repo.

However, I'm not clear on how you keep up to date on the non-master branches in the original repo that you forked. For instance, when I originally forked bitprophet's fabric repository, it contained the following branches:

  • master
  • 0.9
  • 0.9-doc-rewrite (no longer exists)
  • path-and-#24 (no longer exists)

The last two branches no longer exist, and now there is a new branch flexible-task-declarations. I have fetched, merged, and pushed my master branch, so that master, origin/master, and upstream/master all have the same SHA1 hash and point to the same git snapshot. However, I'm not sure how to remove the branches that no longer exist and update the new branches so that my fork is up to date. Do I need to track each upstream branch and then fetch, merge, and push each branch individually, or is there a better way?

+1  A: 

Basically, you have 3 remote Git repo ton consider:

  • local: your current git repo on your workstation.
  • origin: which is your forked version of fabric: cumulusware
  • upstream: bitprophet / fabric, the one at the origin of all the other forked repo

You could add upstream as a remote repo to your local.

 git remote add upstream http://github.com/bitprophet/fabric.git

look at the remote branches

 git branch -r 

and push (delete) the ones which exists at origin but no longer exist at upstream

 git push origin :anOldBranch

Then

 git remote prune origin

to clear the branches on your local repo (which do not exist anymore on origin, since you just deleted them)

The branches which do exist both in origin and upstream need to be synchronized as well (rebasing your local branches on top of those from upstream before pushing your work to origin can be a good way to make very easy pull request to upstream: bitprophet would only have fast-forward merge to do to include your work)

I do not know if you could have a more simple process/command/script to synchronize two distant repositories.

VonC
@Matthew: fixed.
VonC
+4  A: 

Scenario 1: Deleting the branches that no longer exist

To delete the branches that no longer exist, I followed the instructions in the answer to StackOverflow question How do I delete a Git branch both locally and in Github? by issuing the following commands:

$ git push origin :0.9-doc-rewrite
$ git push origin :path-and-#24

Scenario 2: Merging changes in an existing non-master branch

To get the upstream/0.9 branch up to date, I did the following:

$ git checkout --track origin/0.9
$ git fetch upstream
$ git merge upstream/0.9
$ git push

Scenario 3: Tracking the new non-master branches

Note sure this is the best way to handle, but here's what I did:

$ git branch flexible-task-declarations upstream/flexible-task-declarations
Branch flexible-task-declarations set up to track remote branch flexible-task-declarations from upstream.
$ git checkout flexible-task-declarations
$ git push origin flexible-task-declarations

To confirm that all branches are at the same commit:

$ git branch -av

This will show all branches—local and remote—and show the most recent commit message and SHA1 hash.

Web research that may shed light on a better method for handling scenario 3

A key difference between a Git fork, when compared to either a simple Git clone, or an SVN checkout, is that your fork will never keep itself up to date with the master repo unless you do it. Fortunately, there is a simple tool to help you do this. Your fork is separate and equal to the master in Git terms so if you want to track changes to the master you can create a tracking branch in your forked repo and merge those changes into your fork’s master branch whenever you want to commit something. I highly recommend the ‘GitHub’ gem which is a tool you can install to help you easily track changes in any other repository related to yours. See the README text at the bottom of this page for installation and usage: http://github.com/defunkt/github-gem/tree/master

Ignore the Github Fork Queue It's evil! The fork queue is a tool for maintainers who like to pick single commits from contributors but don't wish to merge in their whole branch. If you play around with the fork queue you will corrupt your fork (it can be fixed though, read Something went wrong). Many newbies on github feel like they should do something with the fork queue because there are a lot of possibly conflicting changes in there and they don't know what is the supposed way of keeping one's fork up-to-date. Read Keeping your fork up to date and find out!

Django's Github Workflow

The Django project has instructions on how to Collaborate on Github which uses what appears to be the standard way to handle forking and pulling in upstream changes.

Different Initial Fork Configuration

Long Nguyen's guest post entitled Setting up your Git repositories for open source projects at GitHub on Michael Hartl's blog describes an interesting method to setup a Github repository that you've forked. The goals of this method according to the article are to:

  • Keep the repositories in sync so that each contains the full “official” repository
  • Allow developers to pull in official updates
  • Encourage working on branches other than master
Matthew Rankin
Very interesting. +1
VonC