[Scummvm-devel] How to use your personal github fork

Max Horn max at quendi.de
Wed Apr 27 17:39:56 CEST 2011


Hi there,

for various reasons I thought it'd be a good idea to explain how to make good use of the github fork feature, and to describe a basic workflow involving your personal fork of the scummvm repository. I guess a version of this should be put onto a Wiki page. There are several people on this list who know a lot more about git than I do, and maybe they can help improve this guide, and correct its flaws.

Cheers,
Max



Preliminaries
=============
I assume that you are familiar with the basics of git, have a github account, and have adjusted your local git config to contain info about your github user account, as per <http://help.github.com/git-email-settings/>.

In addition, if you are on a unixy system, I recommend taking a look at the "hub" tool <http://github.com/defunkt/hub> which makes it easier to fork repositories, clone other people's repositories etc. But I will not assume that you are using it.


What is a github fork and why use it?
=====================================
A github fork is a clone of another github hosted repository (say, scummvm/scummvm) which is located under your github user account (say fingolfin/scummvm). It allows you to publish changes you make to ScummVM (preferably in a topic branch), but which you do not want to / cannot push to the regular scummvm repository yet.
It's a good place to stage bigger changes. It's also very easy to ask the ScummVM team to review your changes made in a public github fork, and to optionally merge them into scummvm/scummv, via a so-called "pull request" <http://help.github.com/pull-requests/>.

How to create a github fork?
=============?==============
See here <http://help.github.com/fork-a-repo/>. Essentially, you use the "fork" button on <https://github.com/scummvm/scummvm>. Then, clone your new fork. You can now work in this clone as in a clone of scummvm/scummvm, but pulls and pushes now go to / come from your fork.

How to use your github fork?
============================
In the following, I will try to describe a workflow that is hopefully effective, safe, and relatively easy to use. Other workflows are possible, and you are welcome to use them; the one here tries to minimize the risk of messing up the scummvm/scummvm repository, and to avoid situations in which you need to do complicated stuff you correct mistakes you made.

Over time, your fork will start to *deviate* from scummvm/scummvm. In particular, it will not automatically receive updates made to scummvm/scummvm. So, you will want to regularly sync your fork and its master branch against the master branch of scummvm/scummvm. This is easiest if your fork's master branch never receives any custom commits; always keep it identical to (a possibly old version of) the scummvm/scummvm master branch. All your own work should go to branches, ideally one branch for every topic you are working on (so-called topic branches). 

Initial Setup
-------------
This is how I did the initial setup for it for my personal fork:

1) Clone the fingolfin/scummvm repository
   git clone git at github.com:fingolfin/scummvm.git scummvm-fingolfin
   cd scummvm-fingolfin

2) add a "remote" for the official scummvm/scummvm repository (I will use "upstream" as remote name, to match the github docs; personally, I prefer using the remote "username", so in this case I would have used "scummvm" instead of "upstream". Pick whatever you like)

A read-only remote can be added like this:
   git remote add upstream git://github.com/scummvm/scummvm.git
If you have write access, you may want to instead add a read+write remote, e.g. using the SSH protocol:
   git remote add upstream git at github.com:scummvm/scummvm.git

3) Retrieve the latest data from scummvm/scummvm
   git fetch upstream

Sync master branches
--------------------
To sync my master branch with the upstream master branch, I can now do this, assuming that "master" is the currently active branch (if not, use "git co master" to switch to it):
    git pull upstream master
    git push

Working with code
-----------------
Usually, any code I make goes first into a branch:

  git co -b new-cool-feature

Let's edit a file (e.g. modify base/main.cpp to print "hello, world"). Commit this as usual; note that the commit will land on the new-cool-feature branch, not master.

  ... edit base/main.cpp ...
  git add base/main.cpp
  git ci -m "BASE: Add new cool feature"

You can check the difference between the two branches:

  git diff master..new-cool-feature

Now we want the rest of the world to be able to see our marvelous new code, so let's push it to a new branch on our github fork, with identical name:

  git push origin new-cool-feature

With this we have established a connection between our local "new-cool-feature" branch, and the "new-cool-feature" branch on github. From now on we can just do "git push". So let's edit base/main.cpp again, this time maybe by printing a "goodbye, world" at the end. Then, let's commit and push the changes:

  ... edit base/main.cpp ...
  git add base/main.cpp
  git ci -m "BASE: Even better new feature"
  git push

You can look at the result here: <https://github.com/fingolfin/scummvm/tree/new-cool-feature>

At some point, you may want your work to be integrated into the official ScummVM tree. As mentioned above, the easiest way (if you are not a committer) probably is to submit a pull request <http://help.github.com/pull-requests/>. Even people who do have write access often use this, in order to receive feedback on their code.

If you have write access and just want to integrate your changes, do the following (I'll assume you do a merge here, but you can of course also do a rebase):
   git co master
   git pull upstream   # ensure we are in sync with upstream
   git merge new-cool-feature
   git push upstream   # push to upstream
   git push            # push to your fork

[question to the experts: maybe we want to suggest use of --no-ff for the merge ?]


Note: In reality, I sometimes make an exception and skip the creation of a (topic) branch. E.g. if I only want to commit a quick fix to some code. In that case, I might commit the fix into my local master branch, then push the result to both my fork and scummvm
  git co master
  git pull
  ... edit files, add and commit them ...
  git push upstream
  git push

  
Cleaning up your existing clones / checkouts
--------------------------------------------
Maybe you were already using a fork, but were following a different model (or no model at all ;) and would like to adapt to this. E.g. maybe you made commits directly to your master branch, then merged changes from scummvm/scummvm's master branch into that, and now have a messy history which intermingles your own work with upstream work.

Cleaning this up is usually quite simple. Let's assume the most simple case, namely that you made no branches at all and did all your work on master. (If you did use branches, you need to adapt this. Feel free to ask here or on our IRC channel if you need help.)
So, let's assume you are in your local clone of your fork, with master as sole active branch. Make sure that the upstream remote has been added, as described above, so
   git remote add upstream git://github.com/scummvm/scummvm.git
or
   git remote add upstream git at github.com:scummvm/scummvm.git

Now, we fetch the upstream changes, and *rebase* our master branch on that:
   git fetch upstream
   git rebase upstream/master

If all went fine, then this just completely. If you are in bad luck, this will cause an error, and you will have to resolve conflicts. It prints instructions for how to do that. Feel free to ask here or on IRC for assistance with resolving the issues. In the worst case, you can just use 
   git rebase --abort
to give up. 

But let's assume the rebase worked fine, or that you managed to make it work by resolving any conflicts. Now it's time to move any work you have done on master to a branch, so that we don't need to worry about this again in the future. Also, we will reset your local master branch to match the upstream master branch

  git br BRANCH_NAME
  git reset --hard upstream/master

Finally, we can push your work back to your fork:

  git co master
  git push origin master
  git co BRANCH_NAME
  git push origin BRANCH_NAME





More information about the Scummvm-devel mailing list