Git Cheatsheet

It’s small, fast, and github is rad. So I am trying to learn it.

# Setup
git config --global --list
git config --global user.name "Ken-ichi"
git config --global user.email "fortinbras@norway.net"
 
# The colors, children.  Mm-hey
git config --global color.diff auto
git config --global color.status auto
git config --global color.branch auto
 
# Getting Info
git remote -v # Display the remote repository URL
git log # duh
git show COMMIT # equivalent of svn log -r REV_NUM, but with diffs
 
# Diffing
git diff COMMIT1..COMMIT2 # duh
git whatchanged --since="1 day ago" -p # show changes in date range, commit by commit
git diff $(git rev-list -n1 --before="1 day ago" master) # same as above by by file
git log origin/master..master # show changes between remote and local
 
# Committing
git add .
git commit -a
 
# Amending
git commit -a --amend
 
# Reverting
git reset --hard HEAD # revert everything to HEAD
git checkout path/to/file # reset a single file
git checkout HEAD path/to/file # reset a file you just deleted with git rm
git reset --soft HEAD^ # unstage last commit if you forgot something
git fetch --all && git reset --hard origin/master # reset and overwrite conflicting untracked files
git revert COMMIT # undo the changes in a commit in a new commit
 
# Checking out previous states
git checkout COMMIT
git checkout master # to get back
 
# Stashing
git stash # stash changes on this branch so you can switch and work on something else
git stash pop # bring back the stashed changes
 
# Pushing to another repos
# could be local like /path/to/somewhere 
# or ssh://me@there.net/path/to/repos
git push path/to/repos
git push origin master # if you cloned from a remote named origin
 
# to switch origins
git remote rm origin
git remote add origin 'path/to/a/bare/repo'
 
# note that when sharing a repo with others, you will all want to push/pull from a *bare* repo made with 
git clone --bare path/to/repo
# See http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#public-repositories
 
# Branching and merging
git branch new_branch && git checkout new_branch # make a new branch and switch to it
git checkout -b new_branch # same as above
git diff master..new_branch # diff two branches
git merge other_branch
git mergetool -t opendiff # resolve conflicts in a merge with FileMerge
git branch --track localbranchname origin/remotebranchname # track a remote branch.  you might need to git fetch before this will work
git push origin local_branch # push local_branch to a remote repo.  Will create new local_branch in remote if not there already
git checkout --ours path/to/file # just choose our version
git checkout --theirs path/to/file # just choose their version
 
# Collaboration - add an origin, tracking branch, cherry pick
git remote add -f originname git://github.com/username/repo.git
git branch --track localbranch originname/remotebranch # or whatever branch you want
git fetch # pull in updates
git checkout master && git cherry-pick [commit]
 
# Integrating a range of commits from a branch.
# using cherry-pick
git cherry-pick [first commit]..[last commit
# using rebase --onto
git checkout -b integration # create a branch to integrate changes (optional)
git branch -f integration [last commit] # set integration branch to last commit
git checkout -b tmp # create a tmp branch, not sure why this is necessary
git rebase --onto tmp [first commit]~1 integration # replay from 1 before first commit to last commit
# the above will leave you in integration with the range of commits applied. 
# You can then remove tmp and merge/rebase into a more stable branch
 
# note that in a hierarchical repo network, e.g. there is one authoritative
# repo and several developers have their own forks, it's usually good practice
# to *merge* from the forks into the authoritative repo, and *rebase* from the
# authoritative repo into the forks. Same applies to dev branches / master
# branch.  I think it has something to do with resolving conflicts, though I
# haven't really hit a major issue with it yet.
 
# Adding a submodule
git submodule init
git submodule add path/to/remote/repo path/to/local/checkout
git submodule update
git commit -m "I just added a submodule"
 
# Updating a submodule
cd path/to/local/checkout
git pull origin master # or wherever you're pulling from
cd ../back/to/main/repo
git submodule update
git commit -m "I just updated a submodule"

I’m just getting started with git.  Turns out if your git binaries are in a path specified in something like .bash_profile on your remote machine, something like git clone ssh://you.com/~you/repos.git will fail with an error like bash: git-upload-pack: command not found because sshd ignores .bash_profile, so git won’t find its binaries. So you need to alter the PATH env var in .bashrc instead. Fun.  The git-clone-pack man page is worth a look.