Free and open source distributed version control system.

Main Features

  • Not a file delta-based (difference) VCS
  • Store a series of references of snapshots i.e stream of snapshots
  • Integrity is verified by checksums i.e SHA-1 used for checksum
  • Stages
    • Modified = Working Directory
    • Stagged = Staging Area
    • Committed = Repository
  • Offline documentation can be accessed using man git or git help <COMMAND> or git <COMMAND> -h

OS and packages

apt install git # debian/ubuntu
yum install git # centos/fedora(dnf, microdnf, rpm, yum)
pacman -S git # arch(pacman)
apk add git # alpine
brew install git # OS X

First Time Setup / Config

git config maintains the configuration settings for all the repositories and users.

ScopeCommand to View (git config)LocationRemark
System–list –system/etc/gitconfigAll users and repos.
Global–list –global~/.gitconfig or ~/.config/git/configone users and all repos.
Local–list –local.git/configone users and one repos.
# List the current used configs
git config --list --show-origin 

# Set the user related configs
git config --global "<YOUR_NAME>"
git config --global "<YOUR_EMAIL>"

# Default Editor used by git
git config --global core.editor vim

# Specify default branch for the repos
git config --global init.defaultBranch main

# Getting single config
git config <CONFIG_KEY>
git config


  • Types
    • Tracked files (Committed + Stagged files)
    • Untracked files
  • Lifecycle
    • Untracked
    • Unmodified
    • Modified
    • Staged
  • .gitignore file is used to specify untracked files
    • lines starting with # are comments and are ignored
    • lines starting with ! are skipped and not included in the untracked files

Add, clone, status, commit commands

git init # Initialize a empty git repository

# To clone a existing repository
git clone <URL>
git clone <URL> <CUSTOM_DIRECTORY_NAME> # Clone the repo in a user defined directory

# Add files for tracking
git add <FILE_NAME/DIRECTORY_NAME> # Recursively add the files

# Checking the status of the Tracked / Untracked files
git status
git status --short or git status -s # Short status

# Commiting the changes
git commit -m "COMMIT_MESSAGE"
git commit -a -m "COMMIT_MESSAGE" # Staging and commiting the changes in a single command


# Checking the changes 
git diff # What changes but NOT staged
git diff --stagged # what changed between stagged and last committed files
git difftool # GUI diff using the default GUI diff tool


# Checking the history and previous commits in reverse chronological order
git log
git log -p # Display history along with the diff changes for each commit
git log --stat # Display history along with the changes count for each file
git log --pretty=oneline # Display only commit messages
git log --oneline # Display only commit messages
git log --graph # Clean graph view from all the branches
git log -<n> # Top n commits to view
git log --since <CUSTOM_DATE_TIME> # Only shows commits since the given datetime
git log --until <CUSTOM_DATE_TIME> # Only shows commits untill the given datetime
git log -S STRING_TO_TRACK # Returns the commits in which the given STRING_TO_TRACK was changed/Updated/Added/Deleted

Basics - II

Making additional changes to the last committed commit

git commit --ammend # Keeps the same commit message but adds the new stagged files to the commit
git cherry-pick <COMMIT_ID> # Pick a specific commit and add it to current checked out branch

Remote Repository Management

git remote # Lists all the remotes
git remote -v # Lists the remotes along with the urls
git remote add <REMOTE_NAME> <REMOTE_URL> # Add a separate remote
git remote add upstream <REMOTE_UPSTREAM_URL> # Add a upstream
git remote show <REMOTE> # Show details of the changes between the remote and local
git remote remove <REMOTE> # Remove a remote from local
git remote rename <OLD_REMOTE_NAME> <NEW_REMOTE_NAME>

git fetch <REMOTE> # Pulls changes from the remote to the local but DOES NOT merge automatically. Manual merging is required.

git pull <REMOTE> # Pulls the changes and merges to local as well
git pull <REMOTE_NAME> <BRANCH_NAME> # Pulls a specific remote branch

git config --global pull.rebase "true" # Rebases when merging


  • Types
    • Lightweight - Pointer to specific commit
    • Annotated - Explicity stored in the commit object along with additional info like tag user name etc
git tags -l / --list # List the tags existing
git show <TAG_NAME> # Display a tag
git tag <TAG_NAME> # Create a lightweight tag
git tag <TAG_NAME> <COMMIT_HASH> # Create a lightweight tag for a old commit
git tag -a v0.1.1 -m "<TAG_NAME>" # Create an annotated tag

git push origin <TAG_NAME> # By Default, tags are not pushed to remote. Manually push

git tag -d <TAG_NAME> # Delete a tag locally
git push origin --delete <TAG_NAME> # Delete a tag from remote

git checkout -b <NEW_BRANCH_NAME> <TAG_NAME> # Creating a new Branch from a tag


git config --global checkout
git config --global branch
git config --global commit
git config --global status


  • Stores a series of snapshots
  • commits stores pointers to commit objects
git branch <NEW_BRANCH> # Only Creates a new branch, Doesn't switch to that branch
git branch -d <BRANCH> # Delete a branch

git checkout -b <NEW_BRANCH> # Creates a new branch and switch to that branch
git checkout <BRANCH> # Switches the HEAD pointer to that branch

git switch <BRANCH> # Checkout this branch
git switch -c <NEW_BRANCH> # Creates a new branch and switches to that branch.


  • converge the diverged code commits
git checkout <MASTER_BRANCH> # Checkout to the branch to which you need to merge the branch changes
git merge <BRANCH_NAME> # merges the BRANCH_NAME changes to the current checked out branch i.e MASTER_BRANCH


  • save local changes without committing
git stash # saves the local stashed changes
git stash list # show the stashed changes
git stash pop # load the last stashed changes into the working directory
git stash pop stash@{0} # Pop a specific stash number instead of the latest one
git stash drop stash@{0} # Drop a specific stashed changes
git stash show stash@{0} # show the stashed files


  • Working in a project, and need to use another project within it.
  • Treat the two projects as separate yet still be able to use one from within the other.
git submodule add path/to/submodule
git submodule update --init # First time init of submodule after a fresh clone of the parent repo.
git submodule update --remote # updating to latest tips of remote branches
# Remove a git submodule
git submodule deinit path/to/submodule
git rm path/to/submodule