Git & GitHub: A Complete Guide & Cheatsheet


Introduction
Git is a distributed version control system that helps track changes in code.
GitHub is a cloud-based platform that hosts Remote Git repositories and enables collaboration.
Resources: https://git-scm.com/doc, https://docs.github.com/en
Why Do We Need Version Control?
Track Changes – Easily go back to previous versions if needed.
Collaboration – Multiple people can work on a project without conflicts.
Backup & Recovery – Avoid losing work due to accidental deletions.
Experiment Safely – Try new features on separate branches without breaking the main code.
Documentation – Each commit message serves as a record of what changed and why.
Types of Version Control Systems (VCS)
Local VCS – Stores changes in a local database (e.g., simple file backups).
Centralized VCS (CVCS) – A single server stores all versions (e.g., SVN→ Subversion).
Distributed VCS (DVCS) – Every user has a full copy of the project (e.g., Git). i.e. it has local (Git) and central (GitHub) repositories.
Git is a Distributed VCS, meaning every developer has a complete history of the project. This makes it faster, more reliable, and better for collaboration than centralized systems.
Git + GitHub → Git manages versions locally, while GitHub stores them online for easy sharing!
Git
Installation
Download and install Git: https://git-scm.com/downloads
Set up Git:
git config --global user.name "Your Name" git config --global user.email "your.email@example.com"
Basic Commands
# Initialize a repo
git init
# Clone a repo
git clone <repo_url>
# Check status
git status
# Add changes to staging
git add .
# Commit changes
git commit -m "Commit message"
# View commit history
git log
git init:
git init
is the command used to initialize a new Git repository. It sets up the necessary files and directories for Git to start tracking changes in your project.
Git creates a hidden .git
folder in your project directory, which stores all version control data,
When to Use git init
?
Starting a new project with Git
Converting an existing folder into a Git repository
Reinitializing a corrupted or misconfigured repo
mkdir new-project
cd new-project
git init
cd existing-folder
git init
git add .
git commit -m "Initial commit"
cd my-corrupted-repo
rm -rf .git # Deletes the old Git history (use with caution!)
git init
git clone:
git clone
is used to copy an existing Git repository from a remote location (like GitHub) to your local machine. It creates a complete copy, including all commits, branches, and files.
git clone <repo_url>
# Or with custom folder name
git clone <repo_url> my-folder
git add, git commit, git push, and git pull:
Command | Purpose | Scope |
git add | Adds files to the staging area | Local |
git commit | Saves staged changes with a message | Local |
git push | Uploads commits to a remote repository | Remote |
git pull | Fetches and merges changes from a remote repository | Remote |
git add . # Stage all changes
git commit -m "Updated feature" # Commit changes locally
git push origin main # Upload changes to GitHub
git pull origin main # Get the latest changes from GitHub
git log:
git log
displays the history of commits in your repository. It shows details like:
Commit ID
Author
Date & Time
Commit message
git show:
It is used to display the changes done in specified commit.
This shows:
Commit message
Author & timestamp
Changes made (diff)
git log --oneline -1 #This gives the latest commit ID in short form, e.g., a1b2c3d
git show <commit_id> #Check Changes in the Latest Commit
# OR
git show HEAD
GitHub
Store a Local Repository on GitHub
Create a GitHub account
Create a new repo on GitHub
Push a local repo to GitHub
git remote add origin <repo_url> git branch -M main git push -u origin main
git branch -M main
Rename default branchmaster
tomain
(GitHub now defaults tomain
instead ofmaster
).
Branches
A branch in Git is like a separate workspace where you can make changes without affecting the main codebase.
Why Use Branches?
✔ Work on new features without breaking the main code
✔ Collaborate with multiple developers
✔ Test experimental changes safely
When you create a new branch, it is an exact copy of the branch you're currently on (usually main
).
How It Works?
A new branch starts with the same commit history as the branch it was created from.
Any new changes in the branch won't affect
main
unless merged.
View Branches:
git branch # list all branches
git branch -a # show all local and remote branches
Create a New Branch:
git branch feature-xyz
Creates a new branch called feature-xyz
but doesn’t switch to it.
Switch to Another Branch:
git checkout feature-xyz # Older method (deprecated)
git switch feature-xyz
# Create & Switch in One Command
git checkout -b feature-xyz
#OR new way
git switch -c feature-xyz #Creates and switches to feature-xyz
Create Orphan Branch:
creates a completely new branch without any history from the current branch. An orphan branch starts with no previous commits—it's like a fresh Git repo.
git checkout --orphan new-branch
Merge a Branch into main
# First, switch to main:
git checkout main # or git switch main
# Then merge:
git merge feature-xyz
Delete a Branch
git branch -d feature-xyz # Deletes the branch only if merged
git branch -D feature-xyz # Force deletes the branch (even if not merged)
Push a New Branch to GitHub
git push -u origin feature-xyz # Uploads the branch to GitHub
Push All Local Branches to GitHub
git push --all origin
Push Only the Current Branch
git push origin HEAD
Pull Latest Changes from a Remote Branch
git pull origin feature-xyz # Updates your local branch with remote changes
Rollback
Mistakes happen, and Git provides multiple ways to undo changes, depending on what you need to fix.
1. Undo Unstaged Changes
If you've edited files but haven't added them to the staging area: Restores the file to the last committed state.
git checkout -- <file>
# OR Alternative (New Method)
git restore <file>
2. Undo Staged Changes
If you've added files (git add <file>
), but haven't committed yet: Removes files from the staging area but keeps the changes.
git reset <file>
# unstage everything:
git reset
3. Undo the Last Commit
A) Uncommit + Keep Changes:
git reset --soft HEAD~1 #The last commit is removed, but changes stay staged.
B) Uncommit + Unstage Changes:
git reset --mixed HEAD~1 # The last commit is removed, and changes move to the working directory.
C) Completely Remove the Last Commit (Dangerous ⚠️):
git reset --hard HEAD~1 # The last commit and changes are completely erased.
Undo a Hard Reset: To recovers lost commits (if not garbage collected).
git reflog
git reset --hard <commit-id>
4. Revert a Commit (Safe Way)
If a commit is already pushed, use git revert
git revert <commit-id>
Creates a new commit that undoes the changes.
Safer than
reset
because it preserves history.
5. Discard All Local Changes (Dangerous ⚠️)
# Resets everything to the last commit (use carefully!).
git reset --hard
6. Roll Back to a Specific Commit
A) To moves the branch pointer back and erases newer commits:
git reset --hard <commit-id>
B) To keep changes but move the branch
git reset --soft <commit-id>
7. Restore Deleted Files
If you deleted a file but haven't committed yet: Undo Unstaged Changes
git checkout -- <file>
# OR
git restore <file>
If you deleted a file in a commit: Restores the file from an older commit.
git checkout <commit-id> -- <file>
8. Undo Pushed Commits (Fix Remote)
A) Reset & Force Push (Dangerous ⚠️): This rewrites history and can cause issues in collaboration.
git reset --hard HEAD~1
git push --force
B) Revert Instead (Safer): Creates a new commit that undoes the last commit.
git revert HEAD
git push origin main
Summary
Action | Command | Effect |
Undo unstaged changes | git restore <file> | Resets file to last committed version |
Undo staged changes | git reset <file> | Removes from staging but keeps changes |
Uncommit but keep files | git reset --soft HEAD~1 | Moves HEAD back, keeps files staged |
Uncommit & unstage | git reset --mixed HEAD~1 | Moves HEAD back, files go to working dir |
Undo last commit (delete changes) | git reset --hard HEAD~1 | Deletes last commit & all changes |
Roll back to a specific commit | git reset --hard <commit-id> | Deletes commits after the given one |
Undo pushed commit safely | git revert <commit-id> | Creates a new commit that reverts changes |
Undo pushed commit forcefully | git reset --hard HEAD~1 && git push --force | Removes last commit from remote (dangerous) |
Restore deleted file | git checkout -- <file> | Recovers deleted file |
Recover lost commits | git reflog && git reset --hard <commit-id> | Restores accidentally deleted commits |
✅Use git revert
if you already pushed changes (safe).
✅ Use git reset --soft
if you haven’t pushed and just want to undo a commit.
❌ Avoid git reset --hard
unless you are 100% sure (it erases history).
Semantic Versioning & Git Tags
What is Semantic Versioning?
Semantic Versioning (SemVer) is a standard way to version software, using: MAJOR.MINOR.PATCH
Example: v2.3.4
Version Type | When to Update? | Example |
MAJOR (2.x.x ) | When making breaking changes | 1.0.0 → 2.0.0 |
MINOR (x.3.x ) | When adding new features (backward compatible) | 2.2.0 → 2.3.0 |
PATCH (x.x.4 ) | When fixing bugs (no feature changes) | 2.3.3 → 2.3.4 |
What is a Git Tag?
A Git tag marks a specific commit, commonly used for versioning (releases, checkpoints, or milestones).
Lightweight Tags – Just a reference to a commit
Annotated Tags – Stores metadata (message, author, timestamp, etc.)
Creating & Managing Git Tags
1. Create a Tag:
Lightweight Tag (Simple):Tags the current commit as v1.0.0
git tag v1.0.0
Annotated Tag (With Message):
git tag -a v1.0.0 -m "First stable release"
2. List All Tags:
git tag
3. Checkout a Tag (View Old Version)
Switches to a tagged version (detached mode).
git checkout v1.0.0
Want to continue development? Create a branch from the tag:
git checkout -b new-branch v1.0.0
4. Delete a Tag
Delete Locally: Removes the tag from your local repo.
git tag -d v1.0.0
Delete from Remote (GitHub):
git push --delete origin v1.0.0
5. Push Tags to Remote (GitHub)
Push a Single Tag:
git push origin v1.0.0
Uploads all local tags to GitHub:
git push --tags
6. Move an Existing Tag (Re-tag a Commit)
Moves the tag to a new commit.
git tag -d v1.0.0
git tag v1.0.0
git push --force origin v1.0.0
7. Get Details About a Tag
git show v1.0.0
Difference Between Commits & Tags in Git
Feature | Commits 📝 | Tags 📌 |
Purpose | Tracks every change in the repository | Marks important milestones (releases, versions) |
Changes Over Time? | Moves forward as new commits are added | Stays frozen on a specific commit |
Identification | Identified by a SHA hash (abc1234 ) | Has a readable name (v1.0.0 ) |
Checkout | Can checkout a commit using its hash | Easier checkout using a tag name |
Use Case | Detailed history of changes (fixes, features) | Used for versioning & releases (stable versions) |
GitHub Integration | Doesn't show up as a "Release" | Appears in GitHub as a "Release" |
CI/CD & Deployments | Not commonly used | Used for automated deployments & rollbacks |
Can be deleted? | No, unless history is rewritten (rebase ) | Yes (git tag -d v1.0.0 ) |
Creation Command | git commit -m "fix: login bug" | git tag v1.0.0 or git tag -a v1.0.0 -m "Stable release" |
Commits track every change 📜
Tags mark important versions & releases 📌
Use commits for development & debugging
Use tags for stable releases & deployments
Interview questions
What is difference between git fetch and git pull?
Command | What it does | When to use |
git fetch | Downloads changes from remote only | When you want to review before merging |
git pull | Fetches and merges changes automatically | When you’re ready to update immediately |
git fetch
git merge origin/main
#is same as
git pull origin main
Summary:
Git is a distributed version control system that tracks code changes and enables collaboration. GitHub is a cloud-based platform for hosting Git repositories. Version control systems are essential for tracking changes, collaboration, backup, safe experimentation, and documentation. Git, a distributed VCS, offers advantages over centralized systems by providing each user with a full project history. Key Git commands include initializing repositories, cloning, adding, committing, pushing, pulling, and managing branches. Git also provides tools for undoing changes and using semantic versioning with tags for software releases. Tags mark specific commits and are useful for versioning and deployment.
Subscribe to my newsletter
Read articles from Omkar Kasture directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Omkar Kasture
Omkar Kasture
MERN Stack Developer, Machine learning & Deep Learning