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
comments powered by Disqus