I'm Jon Tai on the frontend engineering team.
I go by jtai on Twitter, GitHub, and IGN's Jabber.
You should already have some idea, since you
used Git to apply for Code Foo.
Git is a distributed revision control and source code management system ...
Distributed means you ask people to pull your changes instead of pushing your changes to a central repository.
... with features like cheap local branching, convenient staging areas, and multiple workflows
And it's fast, too.
Follow this handy tutorial at GitHub.
Most of us actually install Git with Homebrew, which we also use to install other stuff like memcache.
Skip the "GitHub for Mac" GUI; if you want a GUI,
try GitX instead.
The complete collection of a project's files
and the history of those files.
Repositories are mirrored to GitHub
and shared with all collaborators.
A personal copy of a repository.
If you don't have write access to a repository, you can make your own copy of it and commit to the copy.
You can publish your fork. You can also ask the original repository's owner to pull your changes.
GitHub makes this process very, very easy.
A copy of a repository, typically
hosted someplace like GitHub.
When you clone a repository, the source repository is automatically added as a remote called
If you're cloning a fork, you probably want to add a remote pointing to the original repository. By convention, this remote is called
You can push changes from your local repository to
origin (or any other remotes you configure).
You can also pull changes from
into your local repository.
Your local repository remembers the state of each remote. This state is updated every time you do a
A staging area for changes.
The index stores the state of all files in the repository.
The index does not automatically reflect the files
in your working directory! Changes must be
explictly added to the index.
A change to a repository, including all of the
metadata associated with that change.
Metadata includes the author, the date, a short log message, and the state of all files in the repository.
The first commit in a repository has no parents.
Most commits have one parent, but some commits
can have more than one parent.
A line of development; a series of commits.
By convention, the "main" branch is called
Each commit already knows its parent, so a branch only needs to reference the last commit in the branch.
Branches allow development to occur in parallel.
Branches are usually merged with other branches to reunite separate development efforts.
Makes a personal copy of a repository.
You will want to do all your branching
and committing in your own fork.
When you're ready to ship, submit a pull request.
(More on pull requests later.)
GitHub has a guide on forks.
git clone firstname.lastname@example.org:ign/project.git
Makes a local copy of the remote
repository for you to work in.
Each project has its own unique URL; check the project's page on GitHub for the URL you should use.
If you have a fork, make sure to clone the fork,
not the original repository.
git clone email@example.com:jtai/project.git
Unless you really screw up your local repository, you should only need to clone each project once.
git checkout -b <branch>
Creates a new branch off of the current branch's latest commit. It also switches to the new branch.
You should create a branch for every feature
or bug you work on. More on this later.
To switch branches, use
git checkout <branch> (without the
If you need the branch on a second machine, first make sure it's pushed to GitHub from the original machine.
Then do a
git pull on the second machine, and use
git checkout <branch> to switch to the branch.
Shows you the state of your working directory,
the index, and the remote.
# On branch master # Your branch is ahead of 'origin/master' by 5 commits. # # Changes to be committed: # (use "git reset HEAD
..." to unstage) # # modified: assets/images/logo.png # # Changes not staged for commit: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: index.html # # Untracked files: # (use "git add ..." to include in what will be committed) # # assets/images/git_url.png # assets/images/programming.gif
Shows you the changes in your working
directory relative to the index.
So if you add a change to the index, it won't show up in
git diff anymore.
This lets you add changes to the index one by one until
git diff output is empty.
git checkout -- <file>
Discards uncommitted changes in your working
directory by re-checking out the file.
git checkout can also take a branch argument,
"what comes after this is a file".
This operation is called "revert" in some other systems
(CVS, Subversion, Mercurial)
git add <file>
Adds a file (or the changes to a file, if the file is
already managed by Git) to the index.
Unlike some other systems, you have to add a file
to the index every time it changes, not just the
first time you add the file.
To view changes that have been staged in the index, use
git diff --cached
You will be prompted for a commit message,
then the changes staged in the index
will become an actual commit.
The first line of a commit message should be
a short summary of the changes you made
(50 characters or less).
If necessary, a more detailed explanation (perhaps
of why you made the change) should follow
after an empty blank line.
commit b8803de64e724cde0e802053e031189726b5caed Author: Jonathan Tai <> Date: Fri Jul 6 11:34:00 2012 -0700 Updated object migration to use new release status field for all regions This applies the same change as c1a28a09c0721be9105895992524f5c1105ddbc8, except for UK, AU, and JP. Since the Object API is already using the new "status" field, UK/AU/JP status updates were not being written to the API because the migration script was setting the old "released" field.
More guidelines (and rationale) can be
found in this blog post.
git diff master...<branch>
Shows the changes in your branch that are not in master.
You should compare your branch with master before you push (publish your code) to make sure the changes
are what you think they should be.
You should make sure your local
is up to date before diffing.
Changes in master that are not in your branch will not be shown. To show the actual diff, use two dots instead.
git diff master..<branch>
git push -u origin <branch>
Pushes changes in
your changes accessible to others.
-u argument sets up your local branch
to track the remote branch so it will be
updated if you do a
git pull later.
It's a good idea to push at least once a day
to ensure your work is backed up in case
something bad happens to your laptop.
Updates your current branch with
git pull is actually a shortcut for two other operations:
git fetch and
Downloads changes from a remote repository, updating your local repository. Your local branches and working directory are not updated.
The newly-downloaded changes from the remote branch will be merged into your current local branch.*
The working directory is also updated.
*If your current local branch is configured to track a remote branch
Since a merge is performed, you should make sure your working directory is clean before doing a
git merge <branch>
Merges changes from
branch into your current branch.
There are two typical reasons to do this.
If you're working on a branch for a long time, you will want to periodically merge
master into your branch.
Switch to your branch with
git checkout <branch>, then do
git merge master.
When you're done with a branch, you will want to
merge your branch into
git checkout master,
git merge <branch>.
If conflicting changes are introduced in the two branches being merged, a merge conflict will occur. Ask for help.
You should create a branch for every
feature or bug you work on.
Branches allow you (or us as a team) to
work on separate things in parallel.
These things can then be reviewed,
tested, and merged separately.
Keeping changes isolated until they're ready keeps your
master branch deployable at all times.
GitHub pull requests are an easy way to track proposed changes. Just push your branch, then open a pull request.
Everyone with write access to the target repository
will be notified. The change can be discussed as
a whole or line by line.
Generally a reviewer would accept your pull request by merging the changes, but if your project uses a shared repository,
you may be asked to merge and
close your own pull request.
What happens after the code is merged
depends on the project.
Forks can be little more complicated because you have two repositories to deal with instead of just one.
Fortunately, the concepts are mostly the same. Work in a branch (in your fork), pull periodically from upstream, and submit a pull request when you're ready to ship.
(Diagram is vastly over-simplified)
If you're using a fork, don't commit to the
master branch (or any branch that exists in
master aside for tracking
and make all your changes in a branch.
To update your
master branch, switch to
do a fetch and merge from
upstream, then push it to
your fork (
git checkout master git fetch upstream git merge upstream/master git push origin master
Once your fork (
origin) is up to date, merge from master into your branch to update it just as you
would if you weren't using a fork.
git checkout <branch> git merge master
(Yes, this will be over soon.)
Branches are cheap, and commits are fast. Don't work on something for a week, then check it all in at once.
(But don't over-do it, every commit should at least parse/build)
Don't be afraid to delete code, or even entire files. As long as that code was previously committed, it will be in the revision history forever, so we can always get it back.
Don't add large binary blobs to the repository. Once you add it, even if you delete it, it will take up space in the revision history forever.
Do not use
git pull with a fourth refspec argument,
git pull origin master.
It doesn't do what you think it does.
git pull origin master merges changes
from the remote
master branch directly into
your current local branch.
git pull will only merge a remote branch into a local branch with the same name*.
With a refspec,
git pull acts more like
git merge, so you can accidentally merge two branches when you just meant to update your branch.
Actually, it will use the tracking branch configuration you specified using
git push -u,
but unless you have a really odd configuration, local and remote branch names will be the same
Further, the remote references on your machine are
not updated, so
git status will say you're ahead
of origin when you're really not.
git push origin <branch> is perfectly fine.
In fact, it is encouraged, otherwise you will push all branches.
Any local branches that are out of date will fail to push, and any local branches that have been
deleted on the remote will be re-created.
git help <command>, or
ask one of the engineers!
jtai on Twitter, GitHub, and IGN's Jabber