My Git Cheatsheet

I’ve used Git for many years but it still trips me up. At times I’ve worked primarily in a GUI (like Sourcetree or Fork), and other times directly on the command line. I’ve worked on projects where I’ve been the sole developer and others where I’m part of a large team. Regardless of the tools or context, I’ve learned there are certain need-to-knows. Here’s a list of useful Git commands for my reference and yours.

Note: the following is not an exhaustive list but rather the Git commands I keep coming back to and/or regularly forget. For deeper explanations, see the list of resources at the foot of the article.

Configuration #

Configure your favourite editor to be used for commit messages:

git config --global core.editor "nano"

Configure any setting:

git config [--global] <key> <value>

Start work on a repo #

In Github, find an existing repo (or create a new repo) and grab its URL. Next, clone it from the command line:

cd mycodedir
git clone https://github.com/fuzzylogicxx/dummy.git optionaldirname

Alternatively, you might have begun by working locally before creating the repo in Github:

mkdir dummy && cd dummy
echo "# Welcome to DummyRepo" >> README.md
git init
git add README.md
git commit -m "first commit"

# when ready, go to Github and create empty repo.
# then add as a remote
git remote add origin https://github.com/fuzzylogicxx/dummy.git

# push up, passing -u to set the remote branch as the default upstream branch our local branch will track
# this saves typing out ‘origin master’ repeatedly in future.
git push -u origin master

Remotes #

Remove a remote from your local settings:

git remote rm <name>

Rename a remote:

git remote rename oldname newname

Staging, unstaging and deleting files #

# stage all unstaged files
git add .

# stage individual file/s
git add filename.txt

Unstage with reset (the opposite of git add):

# unstage all staged files
git reset .

# unstage individual file/s
git reset filename.txt

Delete a physical file and stage the deletion for the next commit:

git rm folder/filename.txt

Committing updates #

Commit with a multi-line message:

git commit

Commit with short message:

git commit -m "fix: typo in heading"

Stage and commit all changes in a single command (note: doesn’t work with new, untracked files):

git commit -am "fix: typo in heading"

Branches #

Show all local branches:

git branch

Show all local and remote branches:

git branch -a

Save current state to new branch but don’t yet switch to it (useful after committing to wrong branch):

git branch newbranchname

Create and switch to new branch:

git checkout -b mynewbranch

Switch to an existing branch:

git checkout branchname

Save typing by setting the upstream remote branch for your local branch:

# git branch -u remotename/branchname
git branch -u fuzzylogic/v3

# now there’s no need to type origin master
git pull

Staying current and compatible #

fetch remote branch and merge simultaneously:

git pull remotename branchname

# common use case is to update our local copy of master
git pull origin master

# shorthand when a default upstream branch has been set
git pull

# an alternative is to update (fetch) which does not auto-merge, then 'reset' to the latest commit on the remote
# https://stackoverflow.com/questions/55731891/effects-of-git-remote-update-origin-prune-on-local-changes
git checkout master
git remote update --prune
git reset --hard origin/master

Merge another branch (e.g. master) into current branch:

git merge otherbranch

# a common requirement is to merge in master
git merge master

Rebasing #

git rebase can be used as:

  1. an alternative to merge; and
  2. a means of tidying up our recent commits.

As an alternative to merge its main pro is that it leads to a more linear therefore easier-to-read history. Note however that it is potentially more disruptive therefore not right for every situation.

Say I’ve been working on a feature branch and I think it’s ready.

I might want to just tidy up my feature branch’s commits and can do this with an “interactive rebase”. This technique allows me to tidy my feature branch work to remove trivial, exploratory and generally less relevant commits so as to keep the commit history clean.

I might also want to bring in master to ensure synchronicity and compatibility. rebase sets the head of my feature branch to the head of master then adds my feature branch’s commits on top.

While it’s a good idea to rebase before making a PR, don’t use it after making a PR because from that point on the branch is public and rebasing a public branch can cause problems for collaborators on the branch. (The only exception to the previous rule is if you’re likely to be the only person working on the PR branch)

Rebuild your feature branch’s changes on top of master:

git checkout master
git pull origin master
git checkout myfeaturebranch
git rebase master

Force push your rebased branch (again, only when you’re unlikely to have/require collaborators on the PR):

git push --force origin myfeaturebranch

Tidy a feature branch before making a PR:

git checkout myfeaturebranch
git rebase -i master

# just tidy the last few (e.g. 3) commits
git rebase -i HEAD~3

# this opens a text editor listing all commits due to be moved, e.g.:
pick 33d5b7a Message for commit #1
pick 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3

# change 'pick' to ‘fixup’ to condense commits, say if #2 was just a small fix to #1
pick 33d5b7a Message for commit #1
fixup 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3

For more detail, read Atlassian’s guide to rebasing.

Reviewing #

Show commit history (most recent first; q to quit):

git log

# compact version
git log --oneline

# limit scope to commits on a branch
git log branchname

Check if your feature branch is trailing behind:

# show commits in master that are not yet in my feature branch
git log --oneline my-feature..master

# show commits on remote branch that are not yet in my local branch
git log --pretty='format:%h - %an: %s' new-homepage..origin/new-homepage

# show commits by me that included “heroku” and that changed file Gemfile
git log --author=Demaree --grep=heroku --oneline Gemfile

Review differences between staged changes and last commit:

git diff --cached

Review changes between a given version/commit and the latest:

git diff 591672e..master

Fixing Things #

Undo all the changes in a given commit:

git revert 591672e

Alter the previous commit (change the message and and/or include further updates):

# assuming there are no staged files, this amends the commit message only.
# if files are staged, it combines the staged changes with the previous commit.
git commit --amend

Move current branch tip backward to a given commit, reset the staging area to match, but leave the working directory alone:

git reset 591672e

# additionally reset the working directory to match the given commit
git reset --hard 591672e

See what the app/site was like (e.g. whether things worked or were broken) at a given previous commit, noting the following:

  • You’re now “detatched”, in that your computer’s HEAD is pointing at a commit rather than a branch.
  • You’re expected to merely review, not to make commits. Any commits you make would be “homeless”, since commits are supposed to go in branches. (However you could then branch off.)
git checkout 591672e

Grab one or more commits from elsewhere and drop into your current branch:

git cherry-pick 591672e

# grab the last commit from a branch e.g. master
git cherry-pick master

Fix a pull that went wrong / shouldn’t have been done:

git pull origin branchname
# whoops!

git reflog
# shows a list of every thing you've
# done in git, across all branches!
# each one has an index HEAD@{index}
# find the one before you broke everything

git reset HEAD@{index}
# magic time machine

Useful external resources #

External Link Bookmark Note Entry Search