maateen

Git Cheat Sheet - The Ultimate Guide

Git is a free and opensource version control system. Surely, we have more VCS like Bazaar, Mercurial, and SVN. But Git is the most popular and widely used VCS. It is another creation of Linus Torvalds. He created it in 2005 for development of the Linux kernel. In software development, it is used for source code management, especially for tracking changes.

In this blog, we aren’t gonna learn Git. We will just document some very necessary Git commands for day-to-day usage. We are gonna call this document/blog/guide by cheat sheet. A cheat sheet is a quick reference guide. By the way, Git is very easy to learn. You will find tons of tutorials on the internet for that.

Setting up a Git repository

A Git repository, mostly known as repo, refers to a virtual storage for saving versions of a project. Within a repo, we can access all the versions of the project. Let’s assume that you need to initialize a Git repo in any directory. In that case, you may run the following command:

$ git init

If you have any existing repo hosted on the cloud, then you may need to clone it locally:

$ git clone <repo url> <destination>

is an optional command line argument. If you don’t pass it, then the repo will be cloned into the current working directory.

You may want to host your local repo on the cloud, for example, on GitHub, GitLab, or BitBucket. They are all famous source hosting platforms. To host on them, they will provide you a repo URL. You may need to set up this into the local repo:

$ git remote add <remote> <repo url>

is just a name and helps to identify the repo URL by name later.

Configuring Git

There are three types of configuration:

  • Local: Refers to repository specific configuration stored in /.git/config.
  • Global: Refers to user-specific configuration stored in .gitconfig in user’s home directory.
  • System: Refers to system-wide configuration stored in /etc/gitconfig.

To set the author name and email of the current user for all commits, we can run the following commands:

$ git config --global user.name <author name>
$ git config --global user.email <author email>

To create a shortcut for Git command, we can run the following command:

$ git config --global alias.<git-alias> <git-command>

Staging Changes

Before saving any changes to the repository, we need to stage them. Staging changes refer to adding changes to the repo. To stage changes of a file or directory, we can run the following command:

$ git add <file or directory>

To stage changes of all new and modified files and folders (without deleted), we can run the following command:

$ git add .

To stage changes of all modified and deleted files and folders (without new), we can run the following command:

$ git add -u

To stage changes of all new, modified and deleted files and folders, we can run the following command:

$ git add -A

Saving Changes

After staging changes, we can save them with a message, called commit. Commit refers to the snapshot of the project. In a repo, we can switch between commits and can go back to any snapshot anytime. To save all staged changes in a repo, we can run the following command:

$ git commit -m "<message>"

Every commit needs a message. A message refers to the changes made with the commit. We need to write a sensible message with every commit.

Using Branches

A branch in Git is simply a lightweight movable pointer to one of the commits. In other words, a branch represents an independent line of development. The default branch name in Git is master. To list all branches of a repo, we can run the following command:

$ git branch

To list all remote branches, we can run the following command:

$ git branch -a

To create a new branch, we can run the following command:

$ git branch <branch>

To switch to a branch, we can run the following command:

$ git checkout <branch>

To create a new branch and immediately switch to it, we can run the following command:

$ git checkout -b <branch>

To rename the current branch, we can run the following command:

$ git branch -m <new branch name>

To delete a branch if it doesn’t have unmerged changes, we can run the following command:

$ git branch -d <branch>

To delete a branch forcefully, we can run the following command:

$ git branch -D <branch>

Stashing Changes

Stashing refers to saving uncommitted changes for later use and using them when needed. To stash uncommitted changes, we can run the following command:

$ git stash

git stash command doesn’t stash untracked files. To stash uncommitted changes including untracked files, we can run the following command:

$ git stash -u

To stash uncommitted changes including ignored and untracked files, we can run the following command:

$ git stash -a

To use the stashed changes, we can run the following command:

$ git stash apply

To remove the stashed changes and reapply to project, we can run the following command:

$ git stash pop

Assume, we have stashed our current changes. Then, we have stashed again after making some changes. This will create multiple stashes. To see the stash list, we can run the following command:

$ git stash list

To use the stashed changes from the stash list, we can run the following command:

$ git stash pop stash@{<index>}

To create a branch from stash, we can run the following command:

$ git stash branch <branch> stash@{index}

Comparing Changes

To compare changes between uncommitted changes and the last commit, we can run the following command:

$ git diff

To compare changes between two different commits, we can run the following command:

$ git diff <commit hash-1> <commit hash-2>

To compare changes between two different branches, we can run the following command:

$ git diff <branch-1> <branch-2>

To compare changes in a file between two different branches, we can run the following command:

$ git diff <branch-1> <branch-2> <file>

Merging Branches

Merging branches refers to integrating a branch in another branch. To merge a different branch into the current branch, we can run the following command:

$ git merge <branch>

To merge multiple different branches into the current branch, we can run the following command:

$ git merge <branch-1> <branch-2>

To set the commit message to be used for the merge commit, we can run the following command:

$ git merge <branch> -m "message"

To merge a different branch into the current branch without making a new commit automatically, we can run the following command:

$ git merge --no-commit <branch>

To refuse to merge and exit with a non-zero status unless the current HEAD is already up to date or the merge can be resolved as a fast-forward, we can run the following command:

$ git merge --ff-only <branch>

To create a merge commit even when the merge resolves as a fast-forward, we can run the following command:

$ git merge --no-ff <branch>

To merge and create a single commit on top of the current branch, we can run the following command:

$ git merge --squash <branch>

To continue the merge process after fixing merge conflicts, we can run the following command:

$ git merge --continue

To abort the merge process and try to reconstruct the pre-merge state, we can run the following command:

$ git merge --abort

Syncing a Repository

To add a new remote repo, we can run the following command:

$ git remote add <remote> <repo URL>

To rename a remote repo, we can run the following command:

$ git remote rename <old name> <new name>

To remove a remote repo with all remote-tracking branches and configuration settings for the remote, we can run the following command:

$ git remote remove <remote>

Fetching Remote Changes

To download commits, files, and refs from a remote repo without integrating into the local repo, we can run the following command:

$ git fetch <remote>

To fetch from all remote repositories, we can run the following command:

$ git fetch --all

To fetch forcefully, we can run the following command:

$ git fetch -f <remote>

Merging Remote Changes

To fetch from and merge with another repository or a local branch, we can run the following command:

$ git pull <remote>

To fetch from and merge with another repository or a local branch without creating a new merge commit, we can run the following command:

$ git pull --no-commit <remote>

To fetch from and merge with another repository or a local branch to ensure a linear history by preventing unnecessary merge commits, we can run the following command:

$ git pull --rebase <remote>

Publishing Changes

To publish local changes of a branch to the remote repo, we can run the following command:

$ git push <remote> <branch>

To publish local changes of all branches to the remote repo, we can run the following command:

$ git push <remote> --all

To publish local changes forcefully even if it results in a non-fast-forward merge, we can run the following command:

$ git push <remote> --force

To remove a remote branch, we can run the following command:

$ git push origin :<branch>

Inspecting a Repository

To see the current state of a repo, we can run the following command:

$ git status

To see the commit history of a repo, we can run the following command:

$ git log

To see the commit history including files and number of lines changes, we can run the following command:

$ git log --stat

To see the precise view of commit history of a repo, we can run the following command:

$ git log --oneline

To see the graphical view of commit history, we can run the following command:

$ git log --graph --decorate --oneline

To see the graphical view of commit history with more details, we can run the following command:

$ git log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

You can run the following command to create a global shortcut git lg for the above command:

$ git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

Undoing Changes

To remove uncommitted changes of a repo, we can run the following command:

$ git clean

To remove only files ignored by Git, we can run the following command:

$ git clean -X

To remove untracked directories in addition to untracked files, we can run the following command:

$ git clean -d

To change the message of the last commit of a repo, we can run the following command:

$ git commit --amend -m "<message>"

To publish this commit to the remote repo, we need to force push over the old commit:

$ git push --force <branch>

With git log --oneline, we can see the precise view of commit history of a repo with commit hash. Each commit hash refers to a state of the repo. To go to any state of the repo, we can run the following command:

$ git checkout <commit>

When we run this command, the repo is in a ‘detached HEAD’ state. It means the branch ref is still pointing to the latest commit. The HEAD ref has been moved, and now points at . To come back to the current state of the repo, we can come back to the branch in where we were before going to the state of the commit:

$ git checkout <branch>

To change current HEAD and branch ref to the specified commit/state without touching the index file or the working tree at all (but resets the head to and leaves all changed files “Changes to be committed”, as git status would put it), we can run the following command:

$ git reset --soft

To reset the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated, we can run the following command:

$ git reset

To reset the index and working tree (any changes to tracked files in the working tree since are discarded), we can run the following command:

$ git reset --hard

To reset the index and update the files in the working tree that are different between and HEAD, but keep those which are different between the index and working tree (i.e. which have changes which have not been added), we can run the following command:

$ git reset --merge

To reset index entries and update files in the working tree that are different between and HEAD, we can run the following command:

$ git reset --keep

When we remember what we just committed is incomplete, or we misspelled our commit message or both and we want to leave working tree as it was before reset, we can run the following command:

$ git reset HEAD~

To change the state of the repo to any previous commit with a commit message, we can run the following command:

$ git revert <commit>

To revert the latest commit, we can run the following command:

$ git revert HEAD

To revert the changes specified by the fourth last commit in HEAD and create a new commit with the reverted changes, we can run the following command:

$ git revert HEAD~3

To continue revert operation after resolving conflicts in a failed cherry-pick or revert, we can run the following command:

$ git revert --continue

To clear the sequencer state after a failed cherry-pick or revert, we can run the following command:

$ git revert --quit

To cancel the operation and return to the pre-sequence state, we can run the following command:

$ git revert --abort

Please be noted that git revert is a safe way to undo changes but git reset is the dangerous method. Also, never reset public history.

References: Atlassian, Git SCM, GitHub Help, Wikipedia