Click the box titles below to expand:

How to's

XSLT

GOOGLE MAPS API

PHP

Antelope

Perl

Document Object Model (DOM)

UNIX

Generic Mapping Tools (GMT)

Miscellaneous

Projects

Courses Taught

Latest Favorites

Mac OS X

Web Development

Beta

How To :: Antelope – Git - Adding new projects

This is an update to an older page that described how to add new projects to Antelope using CVS. Seeing as we have now switched to using Git and the Antelope contrib area is now located on Github I thought it was time to write a post on using this new system, again mainly for my own records.

Comments welcome!

1. Tools for the job

Obviously you need a Git client to run this stuff! Google code hosts the Git application ( http://code.google.com/p/git-osx-installer/), and installs it in /usr/local/git/bin/git. I am running version 1.6.2.2.

You will also need an account on Github. Go get one, it's free!

2. Watching the Antelope contributed Git repository

First things first, you should watch the main Antelope contributed code repository. So, log into your Github account, and go to the Antelope contrib github repo. At the top you will see three buttons: 'fork', 'watch', and 'download' (see image below). You want to click the 'watch' button.

Github screenshot - watch

3. Forking the Antelope contributed Git repository

Next, create your own fork of the Antelope contributed code. Click the 'fork' button and it will create a fork of the contributed code repository in your home page on Github.

Github screenshot - fork

This will be what you push and pull to.

Go back to your home page on Github (click your account name in the dashboard at the top of the page. You should now have something that looks like:

Github screenshot - home user forked branch

4. Get a localhost copy of your branch of the repository

Now you need to go and get your forked repository from the Github server ('clone' it). These will be your local copies to play with in your sandbox. First up, make a play area:

hostname {username} %4> cd sandbox/
hostname {username} %5> mkdir antelope_contrib
hostname {username} %6> cd antelope_contrib/
hostname {username} %7> git clone git@github.com:robnewman/antelope_contrib.git

This will clone your Github branch onto your localhost. Now you can go and play!

5. Add in the Antelope Users Group remote and watch it

You will also want to get the original AUG repository and store a local copy to ensure you keep your branch up to date.

hostname {username} %8> git remote add aug git://github.com/antelopeusersgroup/antelope_contrib.git
hostname {username} %9> git fetch aug

You will want to make sure those most recent AUG changes are in your Github copy of your repository too:

hostname {username} %10> git pull aug
hostname {username} %11> git push -v git@github.com:robnewman/antelope_contrib.git

6. Check the status

It is worthwhile checking the status of the changes you have made. Below is a real example of one of my projects:

hostname {username} %8> git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   file1.html
#	modified:   file2.js
#	modified:   file3.py
#	modified:   file4.py
#	modified:   file5.py
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	../../dbwfserver
no changes added to commit (use "git add" and/or "git commit -a")

7. Add & commit your code

Once you are satisfied you have written all the code you want, you need to add it to your local Git repository and then commit it. Then 'push' it back to the Github online repository. (You might want to add a .gitignore file to ignore any files that should not be pushed back to the Github repository.)

hostname {username} %9> git add .
hostname {username} %10> git commit
[master 3c2ee1a] Modify the index template to display stations, add jquery functions to 
handle station list and event list, add Python functions to create a dictionary of events
 6 files changed, 270 insertions(+), 136 deletions(-)
 create mode 100644 path/to/.gitignore
 rewrite path/to/file (74%)

8. Pushing back to the Github online repository

To make sure your changes are pushed back to the repository successfully, you will need to upload a public SSH key to Github so it knows you have the authority to make the changes. This page has all the information you need to do that.

Now it is just a case of doing a simple 'push' command. You might like to add the verbose option (-v) so you can see that everything is going according to plan:

hostname {username} %9> git push -v git@github.com:robnewman/antelope_contrib.git
Pushing to git@github.com:robnewman/antelope_contrib.git
Counting objects: 24, done.
Delta compression using 2 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (13/13), 2.92 KiB, done.
Total 13 (delta 10), reused 0 (delta 0)
To git@github.com:robnewman/antelope_contrib.git
   3e99ee5..3c2ee1a  master -> master

9. Finishing up

That's it! Of course you will have done a make install of the code on your local machine to ensure everything is working before you committed it, right?

Also, other users might like to know that you have made some changes to the Antelope contributed code repository, or better, would like to download and install your latest cool widget. In that case, you can submit a pull request by clicking the 'pull request' button (see image below).

Github screenshot - pull request

Here you fill out the message and select the recipients. They will get notified that you have made a change to your fork of the repository and they might like to grab those changes and incorporate them into the main branch.

Advanced Git instructions: branches & merging

That is the easy part over. Now, what about merging branches and changing master branches etc. This is some serious Git-fu, and I am no expert. Below is an outline of a project I am working on and how Git was used. Feedback welcome if you know more than me about Git!

This page has some really helpful information to get you started.

What to do if someone else is working on the same project as you?

A pretty common occurrence when working on a project is that someone else also forked the project and is working on the same code-base. Provided you know that you are going to be working side-by-side, the best thing to do here is to also get a copy of their work, with the caveat that there are only two or three of you - if you try and do this with a popular project you will not be able to track everyone's forks!

In my use case, my co-worker Juan has his fork of the project. So I go and get that using the remote add function. This adds a remote name that I specify for my local copy ('juan') for his forked copy of Antelope contrib. By adding the -f argument the remote command immediately follows the add command with a fetch command, getting a copy of everything Juan has done.

hostname {username} %10> git remote add -f juan git://github.com/jreyes1108/antelope_contrib.git

This could also be written as two seperate commands (by removing the -f and adding a fetch command):

hostname {username} %10> git remote add juan git://github.com/jreyes1108/antelope_contrib.git
hostname {username} %11> git fetch juan

We may want to switch which code-base (or branch) we are working on. Using the checkout command below with the -b argument we create and switch to the branch juan/master. Any changes I now make will be to my copy of Juan's code-base.

hostname {username} %12> git checkout -b juan/master

I can switch back to my own fork at any point with the following command:

hostname {username} %12> git checkout master

What happens if the original repository changes while I am working on my fork?

This was one of my main concerns when working on my own fork. How could I keep up with the changes in the original Antelope contributed repository? What happens if my changes, when I push them back into the origin repository, don't work because of some other changes done by someone else? My fears were needless - Git has this figured out. This is known as 'pulling in upstream changes'.

First, you need to get a copy of the original source repository:

hostname {username} %13> git remote add aug git://github.com/antelopeusersgroup/antelope_contrib.git
hostname {username} %14> git fetch aug

Let's quickly do a git remote command to see our list of existing remotes (or repositories) that we are tracking:

hostname {username} %15> git remote
aug
juan
origin

juan is Juan's branch that I am watching. aug is the original Antelope contributed code repository I am watching. My own fork is called origin.

To make sure that I have the latest code from the Github hosted Antelope contributed code repository locally, I use git rebase on the branch I have downloaded, after fetching the latest changes:

hostname {username} %16> git fetch aug
hostname {username} %17> git rebase aug/master

git rebase is a little complex. First off it does a checkout, or switches which branch of the repository I am working on to the one specified in the rebase command. Then it grabs all the changes made to the original repository since I started working on my own fork and applies them in sequence. When it gets to the end of all those changes, it then applies the local changes I have been making on my fork, to my fork. This now has my fork up-to-date with all the changes made to the original repository, plus my work that I have been doing. A good example of this schematically is from the git-rebase man page:

Assume the following history exists and the current branch is "topic":

          A---B---C topic
         /
    D---E---F---G master

From this point, the result of either of the following commands:

    git rebase master
    git rebase master topic

would be:

                  A'--B'--C' topic
                 /
    D---E---F---G master

The latter form is just a short-hand of git checkout topic followed by git rebase master.

This has no rebased my repository in date order and I need to check that the changes I made are working as expected.

Applying changes from another branch to my branch: merging

Now I have my forked code-base up-to-date with the latest changes in the original Antelope repository. All that is left is for me insert the changes that Juan made (and that I have in my local version of his repository called juan).

I do this using the Git command merge. Most of the time this will only apply to two branch heads. The two branches are merged into a single new source tree. When things merge cleanly, this is what happens:

  1. The results are updated both in the index file and in your working tree;
  2. Index file is written out as a tree;
  3. The tree gets committed; and
  4. Your branch HEAD pointer gets advanced.

(from the git-merge manpage). Here it is applied to mine and Juan's branches:

hostname {username} %18> git checkout master
hostname {username} %19> git merge juan/master
hostname {username} %20> git status
# On branch master
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#	history.me
nothing added to commit but untracked files present (use "git add" to track)

If you are feeling brave you can do a git pull which will both fetch the upstream changes and merge them all in one command:

hostname {username} %21> git pull juan master

So here I am fetching the latest changes that Juan has pushed to his Github-housed fork to my local repo 'juan' then merging them all into my master branch.

If I have commits not in Juan's branch a normal merge will occur. If my commits are already in the upstream branch, a fast-forward merge will be done, moving my local branch/fork to the same commit as juan/master. If both repositories have edits to the same location in the same file, we get a merge conflict. These need to be resolved by hand. Yuck. Lets hope that does not happen.

All that now remains is for me to push my changes back to my fork on Github and send a Github pull request to Juan to tell him that I have merged our seperate forks and he might like to do the same thing, so we have all our changes in sync.

hostname {username} %22> git push -v git@github.com:robnewman/antelope_contrib.git

Some Git resources

Comments

From: Geoff Davis

I would HIGHLY recommend making all of your changes in a topic branch
and merging that back into master when ready. Rebasing is messy if you
don't branch before you start making changes.

Workflow would then be:

# Update your local repository from your github:
git checkout master
git pull origin # (or just git pull)

# Merge in the most recent changes from the main AUG repo, and send them back to your repository
git pull aug
git push origin

# Create a new branch to contain your work and check it out
git checkout -b amazingnewfeature

# do work, compile, rinse, repeat

# When you are ready to push changes back up to your repository on
# github, you should do the following to keep all of your changes grouped
# together rather than interleaved with all of the other changes to the
# AUG repo:

git checkout master
git pull aug master
git checkout amazingnewfeature
git rebase master

# Now that you've done this, you have a couple of choices. You can
# either merge your new feature in your master branch and push that back
# up to github, or you can push your "amazingnewfeature" branch to your
# github repository. Arguments can be made either way, but I'd suggest
# that you do the new branch per feature route.

# here's how to do the merge back into master method
git checkout master
git merge amazingnewfeature

# and here's how to push a new branch up to your github repository -
# see also
# http://www.gitready.com/beginner/2009/02/02/push-and-delete-branches.html
git checkout amazingnewfeature
git push origin amazingnewfeature