Version control from first commit to advanced branching strategies, rebasing, conflict resolution, and team workflows.
12
Chapters
50+
Commands
100%
Free
01π
Introduction to Git
Why Version Control Matters
Git is a distributed version control system that tracks changes to your code. Every developer needs Git β it's the foundation of modern software collaboration, CI/CD pipelines, and infrastructure as code.
Why Git?
π
Track Changes
Every change is recorded with who, when, and why. You can always go back.
πΏ
Branching
Work on features independently without breaking the main codebase.
π₯
Collaboration
Multiple developers work on the same project simultaneously.
π
Distributed
Every developer has a full copy of the repository β no single point of failure.
Git vs Other VCS
Feature
Git
SVN
Mercurial
Architecture
Distributed
Centralized
Distributed
Speed
Very fast
Slow on network
Fast
Branching
Lightweight
Heavy
Moderate
Adoption
Industry standard
Legacy
Niche
π‘ Key Concept
Git stores snapshots of your project, not diffs. Each commit is a complete snapshot with pointers to unchanged files.
02βοΈ
Installing & Configuring Git
Setup for Linux, Mac & Windows
Install Git and configure your identity β these settings appear in every commit you make.
Installation
$ sudo apt install gitUbuntu/Debian
$ sudo yum install gitCentOS/RHEL
$ brew install gitmacOS (Homebrew)
$ git --versionVerify installation
First-Time Configuration
TERMINAL# Set your identity (appears in commits)
git config --global user.name "Your Name"
git config --global user.email "you@email.com"
# Set default branch name
git config --global init.defaultBranch main
# Set default editor
git config --global core.editor "vim"
# View all settings
git config --list
π‘ SSH Keys
Set up SSH keys for GitHub/GitLab to avoid typing passwords: ssh-keygen -t ed25519 -C \"your@email.com\" then add the public key to your Git hosting platform.
03π»
Git Basics
Init, Add, Commit, Status & Log
The core Git workflow: initialize a repo, stage changes, commit them, and inspect history.
Core Workflow
TERMINAL# Initialize a new repository
git init
# Check status
git status
# Stage files for commit
git add file.txt # Stage one file
git add . # Stage all changes
git add -p # Stage interactively (patch mode)
# Commit staged changes
git commit -m "feat: add user authentication"
# View commit history
git log --oneline --graph --all
git log --since="2 weeks ago" --author="suresh"
The Three Areas
π
Working Directory
Your actual files on disk. Changes here are \"untracked\" or \"modified\".
π
Staging Area (Index)
Files you've marked for the next commit with git add.
π¦
Repository (.git)
Committed snapshots stored permanently in the .git directory.
.gitignore
FILE# .gitignore β files Git should never track
node_modules/
.env
*.log
dist/
.DS_Store
__pycache__/
*.pyc
.terraform/
*.tfstate
β οΈ Never Commit Secrets
API keys, passwords, and tokens should NEVER be committed. Use .env files (gitignored) or secret managers. If you accidentally commit a secret, rotate it immediately β git history is permanent.
04πΏ
Branching
Create, Switch & Manage Branches
Branches are Git's killer feature. They let you work on features, fixes, and experiments in isolation without touching the main codebase.
Branch Commands
$ git branchList all local branches
$ git branch feature/loginCreate a new branch
$ git checkout feature/loginSwitch to a branch (old way)
$ git switch feature/loginSwitch to a branch (modern way)
$ git switch -c feature/loginCreate and switch in one command
$ git branch -d feature/loginDelete a merged branch
$ git branch -D feature/loginForce delete an unmerged branch
$ git branch -aList all branches (local + remote)
Branch Naming Conventions
Prefix
Purpose
Example
feature/
New features
feature/user-auth
bugfix/
Bug fixes
bugfix/login-crash
hotfix/
Urgent production fixes
hotfix/security-patch
release/
Release preparation
release/v2.1.0
chore/
Maintenance tasks
chore/update-deps
π‘ Pro Tip
Branches in Git are just pointers to commits β they're incredibly lightweight. Create branches freely. A branch costs almost nothing in storage or performance.
05π
Merging & Conflict Resolution
Combine Branches Safely
Merging integrates changes from one branch into another. Most merges are automatic, but sometimes you'll need to resolve conflicts manually.
Target branch has no new commits. Git just moves the pointer forward. Clean, linear history.
π
Three-Way Merge
Both branches have new commits. Git creates a merge commit combining both histories.
π₯
Conflict Merge
Same lines changed in both branches. Git can't decide β you resolve manually.
Merge Workflow
TERMINAL# Switch to the target branch
git switch main
# Merge feature branch into main
git merge feature/login
# If there are conflicts:
# 1. Open conflicted files
# 2. Look for <<<<<<< HEAD ... ======= ... >>>>>>> markers
# 3. Edit to keep what you want
# 4. Stage the resolved files
git add resolved-file.txt
# 5. Complete the merge
git commit
β οΈ Merge Conflicts
When you see conflict markers in a file, don't panic. Read both versions carefully, decide what the final code should be, remove the markers, stage, and commit.
06π
Remote Repositories
Push, Pull, Clone & Collaborate
Remote repositories (GitHub, GitLab, Bitbucket) are where your team shares code. Understanding push, pull, and fetch is essential for collaboration.
Remote Commands
$ git clone urlClone a remote repository
$ git remote -vList remote connections
$ git remote add origin urlAdd a remote
$ git push origin mainPush local commits to remote
$ git push -u origin mainPush and set upstream tracking
$ git pull origin mainFetch and merge remote changes
$ git fetch originDownload remote changes without merging
$ git push origin --delete branchDelete a remote branch
Push vs Pull vs Fetch
Command
What It Does
Changes Local?
git fetch
Downloads remote commits
No β only updates remote refs
git pull
Fetch + merge into current branch
Yes β modifies your branch
git push
Uploads local commits to remote
No β modifies remote
π‘ Best Practice
Always pull before you push to avoid conflicts. Better yet, use git pull --rebase to keep a clean history.
07π
Rebasing
Rewrite History for Clean Commits
Rebasing moves your branch's commits on top of another branch, creating a linear history. It's powerful but requires understanding.
Rebase vs Merge
Aspect
Merge
Rebase
History
Preserves all commits + merge commit
Linear, clean history
Safety
Safe for shared branches
NEVER rebase shared/public branches
Use case
Integrating finished features
Keeping feature branch up to date
Interactive Rebase
TERMINAL# Rebase last 3 commits interactively
git rebase -i HEAD~3
# In the editor, you can:
# pick β keep the commit
# reword β change commit message
# squash β combine with previous commit
# fixup β combine, discard this message
# drop β remove the commit entirely
# Rebase feature branch onto main
git switch feature/login
git rebase main
β οΈ Golden Rule
NEVER rebase commits that have been pushed to a shared branch. Rebasing rewrites commit hashes β your teammates will have conflicts. Only rebase your own local, unpushed work.
08π
Stash, Tags & Undo
Save Work, Mark Releases, Fix Mistakes
Git stash saves uncommitted work temporarily. Tags mark important points like releases. And Git has powerful undo capabilities.
Git Stash
$ git stashSave uncommitted changes
$ git stash listList all stashes
$ git stash popApply and remove latest stash
$ git stash apply stash@{1}Apply a specific stash
$ git stash drop stash@{0}Delete a stash
Tags
$ git tag v1.0.0Create a lightweight tag
$ git tag -a v1.0.0 -m "Release 1.0"Create annotated tag (recommended)
$ git push origin v1.0.0Push a tag to remote
$ git push origin --tagsPush all tags
Undo Mistakes
$ git checkout -- file.txtDiscard working directory changes
$ git restore file.txtModern way to discard changes
$ git reset HEAD file.txtUnstage a file
$ git commit --amendModify the last commit
$ git revert abc123Create a new commit that undoes abc123
$ git reset --soft HEAD~1Undo last commit, keep changes staged
$ git reset --hard HEAD~1Undo last commit, discard everything (DANGEROUS)
β οΈ reset --hard
This permanently destroys uncommitted work. Always double-check before using --hard. Consider git stash first.
09π
Git Workflows
Team Branching Strategies
A Git workflow defines how your team uses branches to develop, test, and release software. Choose based on team size and release cadence.
Common Workflows
πΏ
Git Flow
Main + develop + feature/release/hotfix branches. Best for scheduled releases. Complex but structured.
π
GitHub Flow
Main + feature branches. Simple: branch, PR, review, merge. Best for continuous deployment.
ποΈ
Trunk-Based
Everyone commits to main with short-lived feature branches (<1 day). Best for experienced teams.
π
GitLab Flow
Main + environment branches (staging, production). Good for multiple deployment targets.
Pull Request / Merge Request Best Practices
βKeep PRs small β under 400 lines of changes
βWrite descriptive PR titles and descriptions
βRequest reviews from relevant team members
βRun CI/CD checks before merging
βUse squash merge for clean history
βDelete branches after merging
π‘ Recommendation
For most DevOps teams, GitHub Flow (branch + PR + merge to main) is the sweet spot β simple enough to follow, structured enough for quality.
10π
Git Quick Reference
Essential Commands & Patterns
The most-used Git commands organized by category. Bookmark this chapter.
Setup
$ git initInitialize a new repo
$ git clone urlClone a remote repo
$ git config --global user.name "Name"Set your name
Daily Commands
$ git statusCheck file status
$ git add . && git commit -m "msg"Stage all and commit
Understanding how Git works internally makes you confident with branching, merging, and troubleshooting. These concepts are frequently asked in interviews and help you debug issues faster.
The .git Directory
π
.git/objects
Every commit, tree, and blob is stored here as a compressed object identified by a SHA-1 hash (40 characters, first 7 shown in logs).
π
.git/HEAD
A pointer to the current branch reference. When you switch branches, HEAD changes to point to the new branch.
π
.git/refs
Contains branch pointers (refs/heads/) and tag pointers (refs/tags/). Each branch is just a file containing a commit hash.
π
.git/config
Repository-level Git configuration β remotes, branch tracking, local settings.
Snapshots, Not Diffs
When you commit, Git takes a complete snapshot of all tracked files. Unchanged files are stored as pointers to previous snapshots (not duplicated). Each snapshot gets a SHA-1 checksum β a 40-character hash. The first 7 characters are the short commit ID you see in git log.
The Three Areas + Staging Deep Dive
TERMINALWorking Directory β Staging Area (Index) β Local Repository
# Files in Working Directory are "untracked" or "modified"
# git add moves them to Staging Area β now Git tracks changes
# git commit saves the staged snapshot to the repository
# Skip staging entirely (tracked files only):
git commit -a -m "quick fix"
# This stages ALL modified tracked files and commits in one step
# WARNING: does NOT include new untracked files
# Stage an entire folder:
git add folder1/
# Stage interactively (choose which hunks to stage):
git add -p
HEAD Pointer Explained
TERMINAL# HEAD always points to the current branch tip
git log --oneline
# abc1234 (HEAD -> main) latest commit
# def5678 previous commit
# When you switch branches, HEAD moves:
git switch feature/api
# Now HEAD -> feature/api
# Detached HEAD: checkout a specific commit
git checkout abc1234
# HEAD points directly to a commit, not a branch
# Create a branch from here if you want to keep changes:
git switch -c rescue-branch
VS Code Git Indicators
Icon
Meaning
State
U
Untracked
New file, not yet staged
A
Added
Staged for first commit
M
Modified
Changed since last commit
D
Deleted
File removed
C
Conflict
Merge conflict needs resolution
HTTPS vs SSH Authentication
Method
Setup
Daily Use
HTTPS
Simple β just clone URL
Must enter username/password every push (use credential helper to cache)
SSH
One-time: generate key pair (ssh-keygen -t ed25519), add public key to GitHub/GitLab
Automatic auth on every push β no password prompts ever
π‘ SSH is Standard
In production environments, SSH keys are the standard. Set up once: ssh-keygen -t ed25519 -C \"your@email.com\" then add ~/.ssh/id_ed25519.pub to your Git platform.
Git Diff Variations
$ git diffChanges in working directory (unstaged changes only)
$ git diff --stagedChanges in staging area (about to be committed)
$ git diff main..feature/apiDifferences between two branches
$ git diff HEAD~3Changes since 3 commits ago
$ git diff abc123..def456Differences between two specific commits
Git Log Power Commands
$ git log --onelineCompact one-line commit history
$ git log --pretty=onelineFull SHA + message on one line
$ git log --graph --allVisualize branch tree in terminal
$ git log --since=\"2 weeks ago\" --author=\"suresh\"Filter by date and author
$ git log --oneline -10Last 10 commits only
π‘ Git Graph Extension
Install the \"Git Graph\" VS Code extension for beautiful visual branch history. Click the Git icon in VS Code sidebar β \"View Git Graph\" to see all branches and merges visually.
12πΌ
Interview Questions
Top Git Questions & Answers
The most commonly asked Git interview questions for DevOps and developer positions.
Basic Concepts
β
git switch vs git checkout?
git switch (introduced v2.23) is specifically for switching branches. git checkout does branches + file restore + detached HEAD β too overloaded. Use switch for clarity.
β
What is a checksum in Git?
Every commit gets a SHA-1 hash (40 characters). This uniquely identifies the commit. The first 7 characters are the short ID shown in git log.
β
What does git commit -a -m do?
Stages all modified tracked files AND commits in one command. Skips the staging area. Does NOT add new untracked files.
β
git pull vs git fetch?
fetch downloads remote changes without modifying your branch. pull = fetch + merge. Always pull before pushing to avoid conflicts.
Branching & Merging
β
Merge vs Rebase?
Merge preserves full branch history (creates merge commit, shows branch trees in git log --graph). Rebase creates a clean linear history (single line). Use rebase for local cleanup, merge for shared branches.
β
How to resolve merge conflicts?
Open conflicted files β find <<<<<<< HEAD markers β decide which code to keep β remove markers β git add β git commit. VS Code highlights conflicts with Accept Current/Incoming buttons.
β
What is the merge workflow?
1) git pull origin main (get latest) β 2) git switch main β 3) git merge feature-branch β 4) resolve conflicts if any β 5) git push origin main.
β
Golden rule of rebase?
NEVER rebase commits that have been pushed to a shared branch. Rebasing rewrites commit hashes β your teammates will have conflicts.
Tags & Releases
β
Lightweight vs Annotated tags?
Lightweight: just a pointer to a commit (git tag v1.0). Annotated: contains tagger name, email, date, message (git tag -a v1.0 -m \"Release 1.0\"). Use annotated for releases.
β
How to push tags?
Tags are NOT pushed with git push. Use git push origin v1.0 for one tag or git push origin --tags for all. On GitHub, tags appear in the Releases section with download options.
β
git revert vs git reset?
revert creates a NEW commit that undoes changes (safe for shared branches). reset moves HEAD backward and can destroy commits (--hard deletes work permanently). Use revert on shared branches.
β
Time travel in Git?
git checkout <commit-id> puts you in detached HEAD state at that commit. Create a new branch from there (git switch -c rescue-branch) to work with old code without affecting main.
Best Practices Summary
βAlways pull before you push (git pull origin main)
βUse SSH keys for authentication (not HTTPS passwords)
βWrite descriptive commit messages explaining WHY, not just WHAT
βUse feature branches β never commit directly to main
βUse annotated tags for releases (git tag -a v1.0 -m \"message\")
βUse git revert on shared branches, git reset only on local unpushed work
βInstall Git Graph VS Code extension for visual branch history
βUse git diff --staged to review changes before committing
βRead other people's commit messages to learn good commit style
βAlways set up .gitignore before the first commit