Programster's Blog

Tutorials focusing on Linux, programming, and open-source

Git Cheatsheet

Below is a cheatsheet for Git so we don't become like the guys in this comic:

Image courtesy of xkcd

Related Posts


Similar Commands To SVN

These commands just need to be prepended with git, instead of svn:

  • commit
  • add
  • diff
  • log
  • status


  • mv instead of move
  • rm instead of delete
  • init instead of svnadmin create

Check if Out of Date

git remote update
git status

If you are out of date, then run the following:

git pull

# Alternatively
git fetch  
git merge 

View Diffs

If you want to see the differences that haven't been staged yet against the "base", use:

git diff

If you wish to see the differences that you have staged for committing, then use:

git diff --staged

Restore A Deleted File

If you have various outstanding changes, and want to restore/revert a file that you had deleted at some point and have not committed yet, run the command below to get it back in its last committed form:

git checkout $FILENAME

Unstage A Deletion

The previous example was for when you had deleted a file locally but had not committed yet. If you have a staged deletion of a file that you wish to restore (such as after performing a merge with --no-commit), then you would need to do the following:

git reset -- $FILENAME
git checkout -- $FILENAME

Revert a File

If you want to revert any staged changes to a file, you can revert them with the same command we used to restore a deleted file:

git checkout $FILENAME

... there is also the option to use:

Unstage A File

If you wish to just unstage a file that may or may not already exist in the repo, and you wish to keep the local changes to that file locally, then use:

git reset HEAD $FILENAME

You may think the command below is an "alias" of the one above for unstaging a file. If the file hasn't been committed, then it would unstage the file and keep it locally. However, if it does already exist in the repo, it would actually stage it for removal!

git rm --cached myFile.txt

If you run the command above on a file that already exists in the repo, you will be staging it to be removed!

View History

git log

By default this will not wrap messages in your terminal. If you want to do this, use

git log | less

Also, if you want a visual representation of your branches/history the following command is extremely useful:

git log --oneline \
  --abbrev-commit \
  --all \
  --graph \
  --decorate \

It's an extremely good idea to use an alias for the command above, such as gg.

Quickly Initialize Code In Git

If you have a bunch of code that is not currently under git/version control, then using these commands inside the directory will set up git AND add all the current files to it:

git init
git add .
git commit

Edit Last Git Message

If you wish to change the last commit message you made, and you haven't pushed yet, then you can just use:

git commit --amend 

Then just set the commit message to what you want.

Change Last Commit Author

If you just wish to change the author on the previous commit, then do the following:

git commit \
  --amend \
  --author="Programster <>"


List branches

The command below will list local branches:

git branch  

... and this one will include remote branches:

git branch -a 

Create A Local Branch (Not on Remote)

git branch [a new branch name]

This does not automatically switch you to that branch.

This will create a branch from whatever branch you are currently in rather than always from master.

Create A Local Branch (Not on Remote) - And Switch To It

git checkout -b $NEW_BRANCH_NAME

This will create a branch and automatically switch to it. However, this does not mean it will be on remote.

Create A Local Branch That Tracks Remote


Create A Local Branch That Tracks Specified Remote And With Different Name

This command is particularly useful when one is juggling multiple remotes. E.g. a GitLab and a GitHub, and they both have branches with the same name, but with two different histories. In such a case, it is useful to specify the remote, and use a different name for the branch. E.g. github-develop and gitlab-develop for the develop branch on either source.



git checkout -b github-develop github/develop

Switch Branch

git checkout [name of a local branch]  

Delete a Local branch

git branch -d the_local_branch  

Delete a Remote branch

git push [remote identifier] --delete [branch name]  

For example:

git push origin --delete my-branch  

Delete All Local Tracking Branches That Aren't On Remote

git remote prune origin

Push a Local Branch To Remote and Set to Track

Perform this command if you created a local branch that doesn't exist on remote.

git push -u origin [local branch name]  

The longhand for -u is --set-upstream.

Create A Local Branch That Mirrors Remote

If you have a branch in your central repository, such as Github, then chances are that you want to use the following code to create a local branch of the same name that will track the remote one.

git checkout -t origin/[branch name]  

Checkout a Remote Branch

The command below will allow you to checkout a remote branch and give it a different name, but I recommend you just use the previous command for creating a local branch that mirrors remote instead.

git checkout -b \


Merge a branch and automatically commit if successful:

git merge [branch name]

If you wish to be able to review the changes before commiting the merge (and possibly make some last minute changes), then use:

git merge --no-commit --no-ff branchname

Cherry Picking

If you are not ready to merge a whole branch, but need to grab some of the changes/commits, you want to use the cherry-pick command on each change that you desire. For example:

git cherry-pick 87bafa9

You may wish to do this multiple times and commit as a single commit. In such a case just make sure to use the --no-commit flag on each cherry-pick, and then manually commit when you are done.

git cherry-pick 87bafa9 --no-commit
git cherry-pick 52a08a4 --no-commit
git cherry-pick afa6635 --no-commit
git cherry-pick 1cb5f92 --no-commit
git commit


Unlike SVN, git has a concept of tagging built-in. This means that when creating a release of a php package, you don't branch off into the /tags directory, but simply run:

git tag -a [tag name]  

If you want to see the tags/releases, run:

git tag  

If you want to switch to a tag, execute:

git checkout [tag name]  

Tags do not get pushed to the remote repository automatically with commits. You need to manually run:

git push --tags  

If you want to delete a local tag then use

git tag --delete [tag name]  

Deleting a tag does not result in it being pushed. To delete a remote tag, you need to specify it specifically:

git push --delete [remote name] [tag name]  

If you want to create a tag, but want to give a specific description other than the log on the revision you are tagging, you can use the following:

git tag -a [tag name] -m "[tag description/log]"

Managing Remotes

Display Remotes

git remote -v  

Delete a Remote

git remote rm [remote name]  

Add a Remote (SSH)

git remote add --mirror=push [remote name] [user]@[hostname or IP]:[path to repo]  
git remote add --mirror=fetch [remote name] [user]@[hostname or IP]:[path to repo]  


git remote add --mirror=push origin  
git remote add --mirror=fetch origin  

Note: You can specify just push or fetch if you only intend to perform one of those.

Updating Remote

If you moved your remote repository, then you can just update the remote instead of adding the new location and removing the old one.

git remote set-url origin ssh://

Deleting Remote

git remote remove $REMOTE_NAME

Adjusting/Rewriting History

Rebase Vs Merge

When you want to update a branch from upstream (usually master), you have two options. Merge and rebase. Rebase can be confusing for newcomers coming from SVN, so I just wanted to provide this diagram of the difference.

[Not supported by viewer]

As you can see, the rebase will give you a much cleaner looking history. However, the diagram does not clearly convey the point that in a rebase, each point in the branch's history (purple points) will be considered a new commit after a rebase operation. This is why its okay to rebase your local branches, but it's not okay to rebase something that has gone public. Merging is perfectly okay for things that have been pushed publicly.

I found the section on git rebase from Atlassian most useful.


Use Meld for diffs

Read about how to do it here.

Set Username/Author

To globally set your default 'username' for commits across all projects run the following code:

git config --global [username]  

Note: This will be overriden by the 'local' scale if it exists. To set your username at a local scale, you can run the following command from inside your repo:

git config --local [username]  

Alternatively, you could edit the .git/config file directly.

Set Email

git config --global ""

Enable Colour Coding!

To enable the use of colour for things like diffs:

git config --global color.ui auto  

It is possible to configure colour coding on only certain aspects, or even change the colours themselves, but that is beyond the scope of this tutorial.

Set Default Editor

git config --global core.editor $EDITOR_NAME_HERE  


Git allows you to set aliases. e.g.

git config --global alias.cp cherry-pick  

This would allow you to run git cp instead of git cherry-pick. However this would likely cause confusion with the linux copy command which is also cp.

Repo Types

There are two types of repositories:

  • Bare - Nobody directly uses the repo, but is used for a centralized area for multiple developers to push and pull from. (Like your SVN repo).
  • Shared - This is a "normal" repo that you have set up yourself, and users within the same group can 'pull' (update your code from) or 'push' (apply changes) to it. Likewise you can pull from/push to other peoples shared repos.

These types are indicated with --bare and --shared respectively on the git init command. When not specified, git init will create a shared repository. Click here if you need more info.

Renaming Files

Although git can detect renames, using the mv command on a file, it's probably best just to think of this as deleting a file and creating a new one.

  • If substantial changes are made to the file before the mv, it may not be picked up as a rename
  • Due to the fact that detecting renames is expensive, it is turned off by default and the -M switch has to be given to git log if you do want to see renaming.

Resolving Conflicts

The following command is your best friend:

git mergetool

You may wish to configure meld to act as your merge tool.

Also, you may wish to have 3 files checked out to act like SVN and manually do your diff/merging.

git show :1:./$FILENAME > ./$FILENAME.base
git show :2:./$FILENAME > ./$FILENAME.working
git show :3:./$FILENAME > ./$FILENAME.remote

The above command gives you all the variations of the file, but usually I find that I just want the following:

git show :2:./$FILENAME > ./$FILENAME.working
git show :3:./$FILENAME > ./$FILENAME.remote


It is important to note that the Git protocol does not support authentication. To restrict people's access to your codebase, you need to use the other tools at your disposal. E.g. Setting up an SSH account(s) for the other colleagues to access your repo on. This is unlike SVN, whereby for each Repo, you can configure specific username/password pairs which were used for the 'authors' in the logs.


Add Submodule To Project

git submodule add

Checkout All Submodules

For a repo with submodules, we can pull all submodules using

git submodule update --init --recursive

This will add to, or create a .gitmodules file in your repository.

Update All Submodules

git pull --recurse-submodules


One can add a .gitignore file to a directory and specify files to ignore e.g.


Usually, I find that I want to ensure the folder is committed, but that everything in the folder is ignored, so I will add a .gitignore file to the folder like so:


The ! tells gitignore to ignore that specific path from the ignores. (A double negative).

Ignore Everything But A Specific Directory

In a niche-case where you want to ignore everything in a directory, except for everything under a specific subdirectory, you would do the following



Installation (Linux)

sudo apt-get install git  

Git Data Transport Command Diagram

Install RabbitVCS GUI (Ubuntu)

sudo add-apt-repository ppa:rabbitvcs/ppa -y
sudo apt-get update
sudo apt-get install rabbitvcs-nautilus3

In Ubuntu 13, you may need to perform these extra steps.


Last updated: 12th October 2021
First published: 16th August 2018