When multiple people works on a single project then code management becomes an important step. And there comes Version Control System (VCS) into picture. Version control ensures that at any point of time we can revert back to a particular state of the repository.

Version control system is of two types : Distributed and Centralized. The main difference between these two is that in case of centralized version control, versions are saved only in remote and in case of distributed version control, versions can be saved in remote and in local repository as well. Subversion(SVN) is an example of Centralized VCS and Git is an distributed version control system. In this post I’ll illustrate most of the basic and advance git commands.

Git Setup

$ git init –> Initialize a local repository with git init command to start a git repository
$ git remote add origin <git repo url> –> Link a local git repository to a remote repository with origin as the name of the remote repository or anything you wish. 
$ ssh clone <git repo https/ssh url> –> Clone an existing remote repository.
$ git config --global user.name "xyz" –> Set default name for the author.
$ git config --global user.email "xyz@gmail.com" --> Set default email.
$ git config --global core.editor Vim –> Set default editor for diff and merge commands.

Basic Commands

$ git fetch –> Update the local meta-data from remote.
$ git pull –> Update the local working copy with the remote.
$ git status –> Shows state of workspace and staging area.
$ git add <file or directory> –> Move specified file or directory from workspace to staging area.
$ git add -u –> Update previously tracked files in staging area.
$ git commit -m "message" –> Commit from staging area. Commit means saving a snapshot of current staged changes.
$ git commit -a -m "message" –>Commit directly from workspace instead of staging area. This will commit only the tracked files i.e., files which have been already listed in the index/staging area.
$ git push <remote> <branch> –> Push changes from local branch to remote.
$ git log –> Get detailed logs with commit hash, message, date etc.   $ git log --oneline –> Get logs with just commit hash and message.
$ git log <branch> –> Get logs for a particular branch.
$ git log -n <number_of_commits> –> Limit the no. of commits to show.

Branching Commands

$ git branch –> Displays all the local branches. 
$ git branch -r –> Displays all the remote branches.
$ git branch -a –> Displays all the local and remote branches.
$ git branch <branch_name> –> Create an new branch from current branch.
$ git branch <branch_name> <commit_sha> –> Create a new branch from a particular commit.
$ git checkout -b <new branch name> –> Create a new branch and switch to it.
$ git checkout -b <new branch name> <commit_sha> –> Create a new branch from a particular commit and switch to it.
$ git switch <branch> –> Switch to new branch.
$ git checkout <branch_name> –> switch to a new branch.
$ git push <remote_name> <local_branch> –> Push a local branch to remote.
$ git push - set-upstream <remote_name> <local_branch> –> Push a local branch to remote.
$ git branch -m <old_name> <new_name> –> Rename a local branch.
git branch -m <new_name> –> Rename current local branch.
$ git push origin -u <new_name> –> Push a renamed branch to remote.
$ git branch -d <branch_name> –> Delete a local branch.
$ git push origin --delete <old_name> –> Delete a remote branch.

Stash Area Commands

$ git stash list –> Shows list of all the saved stash.
$ git stash –> Save the current uncommited state aside as a stash stack. to be used later.
git stash push -m "stash_name" –> Save a stash with a particular name.
git stash apply stash@{n} –> Apply a stash while keeping the stash in the stash stack.
git stash pop stash@{n} –> Apply a stash and remove it from the stash stack.
$ git stash drop stash@{n} –> Delete specified stash.
git stash drop stash_name –> Delete a stash save with a name.

Tracking Changes Commands

$ git diff –> Shows difference in state of the files in workspace and  staging area.
$ git diff --staged –> Shows difference in state of the files in index and head.
$ git diff --cached –>Shows difference in state of the files in index and head.
$ git diff HEAD –>Shows difference in state of the files in workspace and head.

Tracking Changes among different stages

$ git diff <commit or branch> –> Shows difference between head and specified branch or commit.
$ git diff <commit_1/branch_1> <commit_2/branch_2> –> Shows difference between two specified commits/branches.
$ code --diff file_1 file_2 –> VScode can also be used to compare any two files. This is not a git command.

Reverting Changes

$ git restore <file> –> Discard changes in workspace. 
$ git checkout <file or directory> –> Discard changes in workspace.
$ git restore --staged <file> or $ git reset <file> –> Unstage a file.
$ git revert <commit> –> It reverts back the workspace to a particular commit specified given that the working tree is clean.
$ git rivert --skip –> Skip revert if failed. 
$ git commit --amend –> Modify the last commit message.
$ git reset --soft <commit> –> It will uncommit changes and move your head back till the mentioned commit. It will just change the head and leave index and workspace as it is.
$ git reset --mixed <commit> –> It will uncommit and also unstage the changes. 
$ git reset --hard –> It will uncommit , unstage and restore the workspace also.
$ git reset --hard –> Discards all the changes in workspace and staging area to match local tree.
$ git reset --hard <remote>/<branch> –> Discards all the changes in workspace, staging area and local tree to match remote tracking branch.
$ git push --force –> After a reset or rebase or ammend, force git push has to done else it won’t be pushed to remote.
$ git clean –> It will remove all the files from workspace which is not being tracked.

Miscellaneous Commands

$ git cherry-pick <commit> –> Pick a particular commit from any branch and apply it to current branch.
$ git merge <branch or commit> –> Merge changes from a particular branch or commit to current branch.
$ git mergetool –> Resolve merge conflicts if auto-merge is failed.
$ git --abort –> Cancel a merge operation.
$ git rebase -i <branch or commit> –> It rewrites the commit history for a particular branch. While rebasing all the current branch commits are applied one after other on top of specified branch/commit. All the commit in the current branch can be modified as we wish. While rebasing, commits can squashed, dropped, picked , amended etc.

Custom git diff and merge tool

For merging or seeing diff, custom editors can be used. Just replace merge with mergetool and diff with difftool in the above mentioned commands. To set vscode as default git editor run the following command: Open the .gitconfig file with git config --global -e and add the following .

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[core]
  editor = code --wait
[diff]
  tool = vscode
[difftool "vscode"]
  cmd = code --wait --diff $LOCAL $REMOTE
[merge]
  tool = vscode
[mergetool "vscode"]
  cmd = code --wait $MERGED

Or alternatively we can use meld also as diff and merge tool.  Meld can be installed in ubuntu with sudo apt-get install meld. Then open .gitconfig file with git config --global -e and add the following .

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[diff]
    tool = meld
[difftool]
    prompt = false
[difftool "meld"]
    cmd = meld "$LOCAL" "$REMOTE"
[merge]
    tool = meld
[mergetool "meld"]
    # Choose one of these 2 lines (not both!) explained below.
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"
    cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"

References