Git Handbook
Git Handbook
How to use this handbook: Every section follows the same pat-
tern — What it does → When to use it → Common issues & fixes
→ Hands-on examples. Work through it top to bottom once, then
use it as a daily reference.
Table of Contents
1. What is Git?
2. git config — Setting Up Your Identity
3. git init — Creating a Repository
4. git clone — Copying a Repository
5. git status — Seeing What Changed
6. git add — Staging Changes
7. git commit — Saving a Snapshot
8. git log — Viewing History
9. git diff — Comparing Changes
10. git branch — Managing Branches
11. git checkout / git switch — Changing Branches
12. git merge — Combining Branches
13. git rebase — Replaying Commits
14. git remote — Managing Remote Connections
15. git fetch — Downloading Without Merging
16. git pull — Fetch + Merge in One Step
17. git push — Uploading Your Work
18. git stash — Parking Unfinished Work
19. git tag — Marking Releases
20. git reset — Undoing Commits
21. git revert — Safe Undo on Public Branches
22. git restore — Discarding File Changes
23. git cherry-pick — Grabbing a Single Commit
24. git bisect — Finding the Bug-Introducing Commit
25. git reflog — The Safety Net
26. git show — Inspecting Any Object
27. git blame — Who Wrote This Line?
28. .gitignore — Excluding Files
29. Real-World Workflows
30. Quick-Reference Cheat Sheet
1
1. What is Git?
Git is a distributed version control system. It tracks every change you
make to files, lets you travel back to any point in history, and lets multiple
people work on the same codebase simultaneously without stepping on each
other.
2. git config
What it does
Sets configuration values that control how Git behaves. Config values live in
three scopes: system (all users), global (your user account), and local (this
repo only). Local overrides global; global overrides system.
When to use it
• First thing you do on a new machine
• Changing your editor, diff tool, or aliases
• Overriding settings for a specific project (e.g., a work email for a work
repo)
2
Syntax
git config [--system | --global | --local] <key> <value>
git config --list # see all active settings
git config --get <key> # see one setting
git config --edit --global # open config file in editor
Examples
# �� Essential first-time setup ���������������������������������������������
git config --global [Link] "Priya Sharma"
git config --global [Link] "priya@[Link]"
3
Issue Fix
Commits show wrong author name git config --global [Link]
"Correct Name" then amend the
commit
Editor opens then Git ignores it Make sure your editor command exits
properly; add --wait for VS Code
Config changes not taking effect Check scope — a --local setting
overrides --global
3. git init
What it does
Creates a brand-new Git repository in the current directory by adding a hidden
.git/ folder that stores all history, config, and objects.
When to use it
• Starting a new project from scratch on your machine
• Turning an existing folder into a Git repo
Syntax
git init # init in current directory
git init my-project # create a new folder and init inside it
git init --bare [Link] # create a bare repo (for servers/remotes — no working tree)
Examples
# �� Start a brand-new project ����������������������������������������������
mkdir my-app && cd my-app
git init
# Initialized empty Git repository in /home/priya/my-app/.git/
4
# �� Rename default branch to 'main' (modern standard) ���������������������
git init --initial-branch=main my-app
# or after init:
git branch -m master main
Issue Fix
fatal: not a git repository You’re running a Git command
outside a repo; run git init first
.git folder accidentally deleted If no remote exists, the history is
gone; always push to a remote
Accidentally init’d inside another Delete the inner .git/ folder: rm -rf
repo inner-folder/.git
4. git clone
What it does
Downloads a complete copy of a remote repository — all files, all branches, all
history — to your local machine, and sets up the remote as origin automati-
cally.
When to use it
• Joining a project that already exists on GitHub/GitLab
• Getting a fresh copy of your own remote repo on a new machine
Syntax
git clone <url> # clone into a folder named after the repo
git clone <url> my-folder # clone into a custom folder name
git clone --branch <branch> <url> # clone and check out a specific branch
git clone --depth 1 <url> # shallow clone — only the latest snapshot
git clone --recurse-submodules <url> # also clone nested submodules
Examples
# �� Standard clone ���������������������������������������������������������
git clone [Link]
cd express
5
git clone [Link] my-express
cd my-express
# �� Clone via SSH (no password prompts after key setup) ��������������������
git clone git@[Link]:your-username/[Link]
Issue Fix
Permission denied (publickey) SSH key not added to GitHub; run
ssh-keygen then add the public key
to GitHub Settings → SSH keys
Clone is extremely slow Use --depth 1 for a shallow clone;
full Linux kernel history is huge
Repository not found Check URL spelling; if private, make
sure you have access
Cloned the wrong branch git checkout -b feature
origin/feature or re-clone with
--branch
5. git status
What it does
Shows the current state of your working directory and staging area: which
files are modified, staged, untracked, or conflicted. This is your most-used
command — run it constantly.
When to use it
• Before staging anything — to see what changed
• Before committing — to verify you staged the right things
• After a merge or rebase — to check for conflicts
6
Syntax
git status # full output
git status -s # short format (compact)
git status -sb # short + current branch name
Examples
# Full output
git status
# On branch main
# Changes to be committed:
# (use "git restore --staged <file>..." to unstage)
# modified: src/[Link]
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# modified: [Link]
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
# [Link]
Issue Fix
Shows many untracked files you don’t Add patterns to .gitignore
care about
File not showing as modified despite Check if it’s ignored; try git add -f
changes filename
Shows conflicts after merge Resolve them manually, then git add
the resolved files
7
6. git add
What it does
Moves changes from the working directory into the staging area (also called
the index). Only staged changes are included in the next commit — this gives
you precise control over what goes into each snapshot.
When to use it
• After editing files you want to include in the next commit
• To stage only specific parts of a file (-p patch mode)
• To track new files
Syntax
git add <file> # stage one file
git add <file1> <file2> # stage multiple files
git add . # stage everything in current directory (recursive)
git add -A # stage all changes + deletions everywhere
git add -p # interactive patch mode — pick hunks to stage
git add -i # interactive menu
Examples
# �� Stage specific files ���������������������������������������������������
git add src/[Link]
git add src/[Link] src/[Link] tests/test_login.py
8
Common issues & fixes
Issue Fix
Accidentally staged wrong file git restore --staged <file> to
unstage
git add . staged files you didn’t Unstage them with git restore
want --staged <file>; add the pattern to
.gitignore before next time
New file not being tracked It must be git added at least once;
.gitignore might be blocking it
Want to add deleted file git add -A includes deletions; git
add . alone may miss them
7. git commit
What it does
Creates a permanent snapshot of everything in the staging area, along with a
message describing what changed and why. Each commit gets a unique SHA-1
hash (e.g., a3f4b2c).
When to use it
• Whenever you finish a logical unit of work (a feature, a bug fix, a refactor)
• Think: “if I had to describe this in one sentence, could I?” — if yes, commit
Syntax
git commit -m "message" # commit with an inline message
git commit # open editor to write a longer message
git commit -am "message" # stage all tracked modified files + commit (skips git add)
git commit --amend # modify the most recent commit
git commit --amend -m "new msg" # rewrite just the last commit message
git commit --no-edit --amend # amend without changing the message (e.g., add a forgotten
Examples
# �� Basic commit �����������������������������������������������������������
git add src/[Link]
git commit -m "Add Stripe payment integration"
9
# Add Stripe payment integration
#
# - Implement charge, refund, and webhook handlers
# - Add unit tests for edge cases
# - Store payment intent ID in the database
# First line = subject (50 chars max)
# Blank line separates subject from body
� Bad:
"fix"
"changes"
"WIP"
"asdfgh"
Issue Fix
nothing to commit, working tree Nothing is staged; run git add first
clean
Committed with wrong author git commit --amend
--author="Name <email>"
--no-edit
10
Issue Fix
Committed to wrong branch Cherry-pick the commit to the right
branch, then reset here
Want to undo the last commit but git reset HEAD~1 --mixed (see git
keep the changes reset)
Committed a secret/password Immediately rotate the secret; use
git filter-repo to scrub history
8. git log
What it does
Shows the commit history — who committed what, when, and why. Endlessly
customisable with flags.
When to use it
• Reviewing what changed recently
• Finding the commit that introduced a bug
• Understanding a project’s evolution
Syntax
git log # full history, most recent first
git log --oneline # one line per commit
git log --oneline --graph --all # visual branch tree
git log -n 5 # last 5 commits only
git log --author="Priya" # filter by author
git log --since="2024-01-01" # filter by date
git log --grep="payment" # filter by message keyword
git log -- src/[Link] # history of one file
git log -p # show the diff for each commit
git log --stat # show changed files + line counts
Examples
# �� Basic log ��������������������������������������������������������������
git log
# commit a3f4b2c (HEAD -> main, origin/main)
# Author: Priya Sharma <priya@[Link]>
# Date: Mon May 5 10:22:00 2025 +0530
#
# Add Stripe payment integration
11
# �� Pretty one-line view ���������������������������������������������������
git log --oneline
# a3f4b2c (HEAD -> main) Add Stripe payment integration
# 9d1e3a1 Fix null pointer in user lookup
# 7b2f0c8 Initial commit
Issue Fix
Log is too long to read Use --oneline and pipe to less; or
git log -n 20
Can’t find a commit Use git log --all to search across
all branches
Log not showing all branches Add --all flag
9. git diff
What it does
Shows the line-by-line differences between two versions of your code: working
directory vs. staged, staged vs. last commit, or any two commits/branches.
12
When to use it
• Before staging — to review your changes
• Before committing — to verify what’s staged
• Comparing branches or tags
Syntax
git diff # unstaged changes (working dir vs. staged)
git diff --staged # staged changes (will go into next commit)
git diff HEAD # all changes since last commit
git diff <commit1> <commit2> # between two commits
git diff main..feature # between two branches
git diff --stat # summary of files changed (no line detail)
git diff -- <file> # diff for one file only
Examples
# �� See what you changed but haven't staged yet ����������������������������
git diff
# diff --git a/src/[Link] b/src/[Link]
# --- a/src/[Link]
# +++ b/src/[Link]
# @@ -10,6 +10,7 @@ def get_user(id):
# - return None
# + user = [Link](id)
# + return user
# �� Quick summary: which files changed and how many lines ������������������
git diff --stat main..feature/payment
# src/[Link] | 48 +++++++++++++++++++++++++++++++++
# tests/test_payment.py | 22 ++++++++++++++++
# 2 files changed, 70 insertions(+)
13
10. git branch
What it does
Lists, creates, renames, and deletes branches. A branch is just a lightweight
pointer to a commit, making branching in Git nearly instantaneous.
When to use it
• Starting work on a new feature or bug fix (always branch off main)
• Cleaning up merged branches
• Renaming a branch
Syntax
git branch # list local branches
git branch -a # list local + remote branches
git branch -r # list remote branches only
git branch <name> # create a new branch (stays on current)
git branch -d <name> # delete (safe — won't delete unmerged)
git branch -D <name> # force delete (even if unmerged)
git branch -m <old> <new> # rename a branch
git branch -vv # show branches + their tracking remotes
Examples
# �� List all branches ������������������������������������������������������
git branch
# * main ← asterisk = current branch
# feature/payment
# bugfix/null-pointer
14
# �� Rename the current branch ����������������������������������������������
git branch -m old-name new-name
Issue Fix
error: branch already exists You already have a branch with that
name; choose a different name or
delete the old one
error: The branch is not fully Use -D to force delete, or merge it
merged first
Remote branch still shows after Run git fetch --prune to clean up
deleting locally stale remote-tracking refs
Accidentally deleted an unmerged Use git reflog to find the tip
branch commit, then git branch <name>
<sha>
When to use it
• Moving between branches
• Starting work on a different feature
• Going back to look at old code (detached HEAD)
Syntax
# Modern (preferred)
git switch <branch> # switch to existing branch
git switch -c <branch> # create + switch
git switch -c <branch> <start> # create from a specific commit/branch
15
# Classic (still works everywhere)
git checkout <branch> # switch branch
git checkout -b <branch> # create + switch
git checkout <commit-sha> # detached HEAD — view old commit
git checkout -- <file> # discard file changes (old syntax)
Examples
# �� Switch to an existing branch �������������������������������������������
git switch main
git checkout main # equivalent, older syntax
# To return to normal:
git switch main
Issue Fix
error: Your local changes would Stash or commit your changes first,
be overwritten then switch
Detached HEAD — commits seem to Create a branch: git switch -c
disappear rescue-branch while still on that
commit
16
Issue Fix
Wrong branch checked out before git stash, switch to correct branch,
committing git stash pop, then commit
When to use it
• Bringing a completed feature branch into main
• Pulling in changes from main into your feature branch to stay up-to-date
• Any time you want to preserve the branch history
Syntax
git merge <branch> # merge branch into current branch
git merge --no-ff <branch> # always create a merge commit (no fast-forward)
git merge --squash <branch> # squash all branch commits into one (then commit)
git merge --abort # abort an in-progress merge (during conflicts)
git merge --continue # continue after resolving conflicts
Examples
# �� Merge a feature branch into main ��������������������������������������
git switch main
17
git merge feature/payment
# If no conflicts: "Fast-forward" or a merge commit is created automatically
# �� Squash merge: collapse 12 messy WIP commits into one clean commit ������
git switch main
git merge --squash feature/payment
git commit -m "Add Stripe payment integration"
# All 12 commits condensed into one; feature branch not recorded in history
Issue Fix
Merge conflict in many files Abort, pull the latest target branch,
re-merge; use a visual merge tool (git
mergetool)
18
Issue Fix
Accidentally merged the wrong git reset --hard HEAD~1 (if not
branch yet pushed) or git revert -m 1
<merge-commit>
Already up to date but changes are The changes might be on a different
missing branch; double-check with git log
--all
Conflict markers (<<<<<<<) Run git grep '<<<<<<<' before
committed committing to catch this
When to use it
• Updating your feature branch with the latest main changes (instead of a
merge)
• Cleaning up messy local commits before a PR (interactive rebase)
• Never rebase commits that have already been pushed to a shared branch
Syntax
git rebase <branch> # rebase current branch onto another
git rebase -i HEAD~3 # interactive rebase: edit/squash/reword last 3 commits
git rebase --onto <new-base> <old-base> <branch> # advanced: transplant commits
git rebase --abort # cancel an in-progress rebase
git rebase --continue # continue after resolving a conflict
git rebase --skip # skip the problematic commit and continue
Examples
# �� Scenario: Update your feature branch with latest main ������������������
git switch feature/payment
19
git rebase main
# Git replays your feature commits on top of the latest main
# Result: linear history, no merge commit
20
Issue Fix
Rebase conflict in every single commit The branches have diverged greatly;
consider merging instead, or git
rebase --abort and plan differently
Pushed rebased commits and Never rebase shared branches; if done,
teammates have errors everyone must git fetch and git
reset --hard origin/<branch>
Accidentally dropped a commit Use git reflog to find the SHA and
during interactive rebase git cherry-pick it back
fatal: Could not read from Network issue; abort and retry
remote repository during rebase
When to use it
• Viewing what remotes are configured
• Adding a new remote (e.g., an upstream repo when contributing to open
source)
• Changing a remote URL (e.g., switching from HTTPS to SSH)
Syntax
git remote -v # list remotes with URLs
git remote add <name> <url> # add a new remote
git remote remove <name> # remove a remote
git remote rename <old> <new> # rename a remote
git remote set-url <name> <new-url> # change a remote's URL
git remote show <name> # detailed info about a remote
Examples
# �� List remotes �����������������������������������������������������������
git remote -v
# origin git@[Link]:priya/[Link] (fetch)
# origin git@[Link]:priya/[Link] (push)
21
# 1. Fork the repo on GitHub
# 2. Clone your fork
git clone git@[Link]:priya/[Link]
cd express
git remote -v
# origin git@[Link]:priya/[Link] (fetch)
# origin git@[Link]:priya/[Link] (push)
# upstream git@[Link]:expressjs/[Link] (fetch)
# upstream git@[Link]:expressjs/[Link] (push)
When to use it
• Checking what’s new on the remote before merging
• Getting remote branches that don’t exist locally yet
• Safer alternative to git pull — look before you merge
Syntax
git fetch # fetch from origin
git fetch origin # explicit
22
git fetch --all # fetch from all remotes
git fetch --prune # also delete stale remote-tracking branches
git fetch origin feature/payment # fetch one specific branch
Examples
# �� See what the team pushed since your last fetch �������������������������
git fetch origin
git log HEAD..origin/main --oneline
# 2c1d0e9 Add user avatar upload
# 3b2e1f8 Fix session expiry bug
When to use it
• Syncing your local main branch with the remote
• Getting a teammate’s latest changes on a shared branch
Syntax
git pull # fetch + merge from tracking remote
git pull origin main # explicit remote + branch
git pull --rebase # fetch + rebase (cleaner history)
git pull --rebase=interactive # fetch + interactive rebase
git pull --no-ff # always create a merge commit
23
Examples
# �� Standard pull ����������������������������������������������������������
git switch main
git pull
# or
git pull origin main
Issue Fix
error: Your local changes would Stash or commit first, then pull
be overwritten
Merge conflict on pull Resolve conflicts, git add, then git
merge --continue or git rebase
--continue
fatal: refusing to merge Two repos that were never connected;
unrelated histories use git pull origin main
--allow-unrelated-histories
Pull created ugly merge commits Use git pull --rebase going
forward
When to use it
• Sharing your commits with teammates
24
• Backing up your work to the remote
• Triggering CI/CD pipelines
Syntax
git push # push current branch to its tracking remote
git push origin main # explicit: push local main to origin/main
git push -u origin feature/payment # push + set tracking (first time pushing a branch)
git push --force-with-lease # safer forced push (checks for remote changes first)
git push --force # force push � dangerous on shared branches
git push origin --delete feature/old # delete a remote branch
git push --tags # push all local tags
Examples
# �� First push of a new branch ���������������������������������������������
git switch -c feature/dark-mode
# ... do work, commit ...
git push -u origin feature/dark-mode
# -u sets the upstream tracking; future 'git push' works without arguments
Issue Fix
rejected: non-fast-forward Pull first, then push; or use
--force-with-lease on your own
branch
src refspec does not match any You’re pushing a branch name that
doesn’t exist locally; check spelling
25
Issue Fix
Pushed a secret/sensitive file Rotate the credential immediately;
use git filter-repo to remove it
from history; force push
Push to protected branch blocked Work is on a feature branch + open a
pull request — this is intentional
When to use it
• You’re mid-feature and need to urgently fix a bug on another branch
• Your working directory is dirty and git switch won’t let you move
• Saving an experiment without committing it
Syntax
git stash # stash tracked file changes
git stash push -m "description" # stash with a name
git stash -u # also stash untracked files
git stash list # see all stashes
git stash pop # apply most recent stash + remove it
git stash apply stash@{2} # apply a specific stash (keeps it in the list)
git stash drop stash@{0} # delete a specific stash
git stash clear # delete all stashes
git stash show -p stash@{0} # see what's in a stash
git stash branch <branch> stash@{0} # create branch from stash
Examples
# �� Classic scenario: urgent bug while mid-feature �������������������������
# You're working on feature/dark-mode, half done
git stash push -m "dark mode: wip – halfway through CSS"
26
# Restore your work
git stash pop
# Back where you were
Issue Fix
stash pop causes conflicts Resolve conflicts manually, then git
stash drop to clean up
Stash disappeared Check git stash list; stashes
persist until manually cleared
Stashed untracked files weren’t Use -u flag; untracked files are
stashed excluded by default
Stash applied to wrong branch Create a branch from the stash: git
stash branch new-branch
stash@{0}
27
When to use it
• Marking a production release
• Creating checkpoints in your history (e.g., before-big-refactor)
Syntax
git tag # list all tags
git tag <name> # create lightweight tag on HEAD
git tag -a <name> -m "message" # create annotated tag on HEAD
git tag -a <name> <commit-sha> # tag an older commit
git tag -d <name> # delete a local tag
git push origin <name> # push one tag
git push origin --tags # push all tags
git push origin --delete <name> # delete a remote tag
git show <tag> # inspect a tag
Examples
# �� Mark a release ���������������������������������������������������������
git tag -a v1.0.0 -m "First stable release: payment + auth complete"
git push origin v1.0.0
28
20. git reset
What it does
Moves the current branch pointer (HEAD) backward to a previous commit, with
three modes that control what happens to the changes in between.
� Warning
Only use git reset on local, unpushed commits. On public branches it
rewrites history and breaks your teammates’ repos.
Syntax
git reset HEAD~1 # undo last commit, keep changes staged (--mixed)
git reset --soft HEAD~1 # undo last commit, keep changes staged
git reset --mixed HEAD~1 # undo last commit, unstage changes (default)
git reset --hard HEAD~1 # undo last commit, DISCARD changes
git reset <commit-sha> # reset to any specific commit
git reset HEAD <file> # unstage a specific file (old syntax)
Examples
# �� Undo the last commit, keep changes to re-edit �������������������������
git reset --soft HEAD~1
# Commit gone, all changes still staged — perfect for rewriting the commit
29
git log --oneline
# a3f4b2c (HEAD) Bad commit
# 9d1e3a1 Add payment ← want to go back here
# 7b2f0c8 Fix null pointer
git reset --hard 9d1e3a1
Issue Fix
Did --hard and lost work Check git reflog immediately —
commits are often still recoverable for
30 days
Reset on a pushed branch broke Teammates must git fetch then git
teammates reset --hard origin/<branch>;
avoid this situation
Reset went too far back git reflog to find the right SHA,
git reset --hard <sha> to return
When to use it
• Undoing a commit that’s already been pushed and shared
• Reverting a release on main without breaking anyone’s history
• Any “undo” on a public branch — always use revert over reset
30
Syntax
git revert <commit-sha> # revert a commit (opens editor for message)
git revert <sha> --no-edit # revert without opening editor
git revert HEAD # revert the most recent commit
git revert HEAD~2..HEAD # revert a range of commits
git revert -m 1 <merge-commit> # revert a merge commit (-m 1 = keep mainline)
Examples
# �� Revert the last commit on main ����������������������������������������
git revert HEAD
# Opens editor with default message: "Revert "Add broken feature""
# A new commit is created that undoes the changes
Issue Fix
error: commit X is a merge, use Add -m 1 to specify which parent to
-m keep
Revert caused conflicts Resolve manually, git add, git
revert --continue
31
Issue Fix
Want to revert multiple commits Revert them individually in reverse
order, or revert a range
When to use it
• Throwing away edits to a file you don’t want
• Unstaging a file you accidentally staged
Syntax
git restore <file> # discard working dir changes (irreversible!)
git restore . # discard all working dir changes
git restore --staged <file> # unstage a file (keep working dir changes)
git restore --staged --worktree <file> # unstage AND discard changes
git restore --source=HEAD~2 <file> # restore file to version 2 commits ago
Examples
# �� Throw away edits to a file ���������������������������������������������
git restore src/[Link]
# � Changes are gone — no undo for this
32
23. git cherry-pick
What it does
Applies the changes introduced by a specific commit (or range of commits) from
anywhere in the history onto your current branch. Useful for picking just one
fix from another branch without merging everything.
When to use it
• Backporting a bug fix from main to a release branch
• Applying one specific commit from a feature branch without merging the
whole thing
• Recovering a commit accidentally committed to the wrong branch
Syntax
git cherry-pick <sha> # apply one commit
git cherry-pick <sha1> <sha2> # apply multiple commits
git cherry-pick <sha1>..<sha2> # apply a range (exclusive start)
git cherry-pick --no-commit <sha> # apply changes but don't commit yet
git cherry-pick --abort # cancel if conflicts are too complex
git cherry-pick --continue # continue after resolving conflicts
Examples
# �� Scenario: fix committed to main, needs to be in release/1.x too ��������
git switch release/1.x
33
# a3f4b2c Added payment form ← should be on feature/payment
Issue Fix
Cherry-pick causes conflicts Resolve files, git add, git
cherry-pick --continue
Wrong commit SHA Use git log --all --oneline to
find the right one
Cherry-picked commit has a Cherry-pick the dependency first,
dependency (relies on a prior commit) then the target commit
When to use it
• “This worked three weeks ago, now it’s broken — what changed?”
• Debugging performance regressions or subtle behavioural changes
• Repos with many commits between known-good and known-bad states
Syntax
git bisect start # start the bisect session
git bisect bad # mark current commit as bad
git bisect good <sha> # mark a known-good commit
git bisect good / git bisect bad # mark each checkout as good or bad
git bisect reset # end bisect, return to original branch
git bisect run <script> # automate with a test script
34
Examples
# �� Manual bisect ����������������������������������������������������������
git bisect start
git bisect bad # HEAD (current) is broken
git bisect good v2.0.0 # tag from 3 weeks ago that worked
35
When to use it
• Recovering “lost” commits after a bad git reset --hard
• Finding the SHA of a branch you deleted
• Understanding the full history of your local HEAD movements
Syntax
git reflog # show all HEAD movements
git reflog <branch> # show movements for a specific branch
git reflog --all # show all refs
git reflog show --date=relative # show with relative timestamps
Examples
# �� Recover from an accidental --hard reset ��������������������������������
# Scenario: you ran git reset --hard HEAD~5 and lost 5 commits
git reflog
# 7b2f0c8 HEAD@{0}: reset: moving to HEAD~5
# a3f4b2c HEAD@{1}: commit: Add Stripe payment integration ← want this back
# 9d1e3a1 HEAD@{2}: commit: Fix null pointer
# ...
git reset --hard a3f4b2c # jump back to before the bad reset
# Your 5 commits are restored!
git reflog
# f1c2d3e HEAD@{3}: checkout: moving from feature/experiment to main
# f1c2d3e was the tip of feature/experiment
36
26. git show
What it does
Displays information about any Git object: a commit’s changes, a tag’s details,
a blob’s content, or a tree’s listing.
Syntax
git show # show last commit diff
git show <sha> # show a specific commit
git show <tag> # show a tag
git show <sha>:<file> # show a file's content at a commit
git show --stat <sha> # show which files changed (no line detail)
Examples
# �� See what a commit changed ����������������������������������������������
git show a3f4b2c
Syntax
git blame <file> # annotate every line
git blame -L 10,25 <file> # only lines 10–25
git blame --ignore-whitespace <file>
git blame -w -C <file> # ignore whitespace + detect moved code
Examples
# �� Find who wrote a suspicious function �����������������������������������
git blame src/[Link]
37
# a3f4b2c (Priya Sharma 2025-05-05 10:22) def charge_customer(amount):
# 9d1e3a1 (Raj Kumar 2025-05-04 15:40) if amount <= 0:
# 9d1e3a1 (Raj Kumar 2025-05-04 15:40) raise ValueError(...)
28. .gitignore
What it does
Tells Git which files and directories to completely ignore — never track, never
show in git status, never accidentally commit.
When to configure it
• Right when you create a repo (before your first commit)
• Whenever a new tool/dependency creates files you don’t want tracked
Syntax rules
# Comments start with #
# Ignore a directory
node_modules/
__pycache__/
.venv/
dist/
build/
38
# Ignore files in any directory named logs
logs/
Examples
# �� Python project .gitignore ����������������������������������������������
cat .gitignore
# __pycache__/
# *.pyc
# *.pyo
# .env
# .venv/
# dist/
# build/
# *.egg-info/
# .pytest_cache/
# .coverage
39
curl -o .gitignore [Link]
Issue Fix
File still showing in git status even File is already tracked; run git rm
after adding to .gitignore --cached <file>
.gitignore itself not in repo Commit it — it belongs in the repo
Rules in .gitignore not working Check for syntax errors; patterns are
case-sensitive
Want to ignore files only for yourself Use .git/info/exclude — works
(not commit the rule) like .gitignore but is never
committed
40
Hotfix Workflow (urgent production fix)
git switch main
git pull
git switch -c hotfix/payment-crash
# ... fix the bug ...
git commit -am "Fix divide-by-zero in payment processor"
git push -u origin hotfix/payment-crash
Daily workflow
git status # what changed?
git diff # see changes (unstaged)
git diff --staged # see changes (staged)
git add <file> # stage file
git add -p # stage hunks interactively
git commit -m "message" # save snapshot
git push # upload
git pull --rebase # download + rebase
41
Branching
git branch # list branches
git switch -c <branch> # create + switch
git switch <branch> # switch
git merge <branch> # merge into current
git rebase <branch> # rebase onto branch
git branch -d <branch> # delete (safe)
git branch -D <branch> # force delete
Undoing
git restore <file> # discard file changes
git restore --staged <file> # unstage file
git commit --amend # edit last commit
git reset --soft HEAD~1 # undo commit, keep staged
git reset HEAD~1 # undo commit, unstage
git reset --hard HEAD~1 # undo commit, discard changes �
git revert <sha> # safe undo (new commit)
Inspection
git log --oneline --graph --all # visual history
git show <sha> # see a commit's changes
git blame <file> # who wrote each line
git reflog # full HEAD history (safety net)
git stash list # see all stashes
Remote
git remote -v # list remotes
git fetch --prune # download + clean stale refs
git push -u origin <branch> # push + set tracking
git push --force-with-lease # safe force push
git push origin --delete <br> # delete remote branch
Mistake Fix
Committed to wrong branch git cherry-pick the commit to
right branch; git reset HEAD~1 here
Committed sensitive data Rotate the secret; git filter-repo;
force push
Accidentally deleted a branch git reflog → find SHA → git
branch name <sha>
42
Mistake Fix
Hard reset lost work git reflog → git reset --hard
<sha>
Merged wrong branch git revert -m 1 <merge-sha> on
public branches
Push rejected git pull --rebase then git push
Conflict markers in commit git grep '<<<<<<<' to find them;
fix + re-commit
.env committed to GitHub git rm --cached .env + add to
.gitignore + rotate secrets
Built to make you an expert — bookmark this, reference it daily, and the com-
mands will become second nature within weeks.
43