0% found this document useful (0 votes)
8 views43 pages

Git Handbook

The Complete Git Handbook is a comprehensive guide designed to take users from beginner to expert in Git, detailing every command, common pitfalls, and fixes. It includes structured sections that explain what each command does, when to use it, and provides hands-on examples. The handbook serves both as a tutorial and a daily reference for Git users.

Uploaded by

Om Vats
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views43 pages

Git Handbook

The Complete Git Handbook is a comprehensive guide designed to take users from beginner to expert in Git, detailing every command, common pitfalls, and fixes. It includes structured sections that explain what each command does, when to use it, and provides hands-on examples. The handbook serves both as a tutorial and a daily reference for Git users.

Uploaded by

Om Vats
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

The Complete Git Handbook

From Zero to Expert — Every Command, Every Pitfall, Every Fix

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.

Core concepts you must understand first

Concept What it means


Repository (repo) The folder Git is tracking, including
all history
Working directory Files you currently see and edit
Staging area (index) A holding area for changes you plan
to commit
Commit A permanent snapshot of staged
changes
Branch A movable pointer to a commit — an
independent line of work
HEAD A pointer to the commit you
currently have checked out
Remote A copy of the repo hosted elsewhere
(GitHub, GitLab, etc.)

The three-stage lifecycle


Working Directory → Staging Area (Index) → Repository (Commits)
(edit files) (git add) (git commit)

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]"

# Set VS Code as the default editor


git config --global [Link] "code --wait"

# Set VS Code as the merge/diff tool


git config --global [Link] vscode
git config --global [Link] 'code --wait $MERGED'

# Always rebase instead of merge on git pull


git config --global [Link] true

# Colorful terminal output


git config --global [Link] auto

# �� Useful aliases ���������������������������������������������������������


git config --global [Link] status
git config --global [Link] checkout
git config --global [Link] branch
git config --global [Link] "log --oneline --graph --decorate --all"
git config --global [Link] "reset HEAD~1 --mixed"

# Use the alias


git lg # pretty log graph

# �� Per-project override (work email) ��������������������������������������


cd ~/work/company-repo
git config --local [Link] "priya@[Link]"

# Verify what's active


git config --list --show-origin

Common issues & fixes

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/

# Create your first file and commit


echo "# My App" > [Link]
git add [Link]
git commit -m "Initial commit"

# �� Turn an existing project into a repo �����������������������������������


cd ~/existing-project
git init
git add .
git commit -m "Initial commit: add existing files"

4
# �� Rename default branch to 'main' (modern standard) ���������������������
git init --initial-branch=main my-app
# or after init:
git branch -m master main

Common issues & fixes

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

# �� Clone into a custom folder ���������������������������������������������

5
git clone [Link] my-express
cd my-express

# �� Shallow clone (faster for large repos, CI pipelines) �������������������


git clone --depth 1 [Link]
# Downloads only the latest commit — no history

# �� Clone a specific branch ������������������������������������������������


git clone --branch develop [Link]

# �� Clone via SSH (no password prompts after key setup) ��������������������
git clone git@[Link]:your-username/[Link]

Common issues & fixes

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]

# Short format — two-column status codes


git status -s
# M src/[Link] ← staged modification
# M [Link] ← unstaged modification
# ?? [Link] ← untracked
Status code legend (short format):
Column 1 = staging area Column 2 = working directory
M = modified A = added D = deleted ? = untracked ! = ignored

Common issues & fixes

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

# �� Stage everything �������������������������������������������������������


git add . # from current directory down
git add -A # entire repo (even if you're in a subdirectory)

# �� Stage only part of a file (interactive patch mode) ���������������������


# Scenario: you made two unrelated fixes in one file.
# Stage only the first fix so each commit is focused.
git add -p src/[Link]
# Git shows each "hunk" (block of changes) and asks:
# Stage this hunk [y,n,q,a,d,s,e,?]?
# y = yes, n = no, s = split hunk further, e = edit manually

# �� Check what's staged ����������������������������������������������������


git diff --staged # see exactly what will be committed

# �� Unstage a file (keep the changes in working directory) �����������������


git restore --staged src/[Link]

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"

# �� Multi-line commit message (best practice for significant changes) �������


git commit
# Opens editor; write:

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

# �� Stage and commit tracked files in one command ��������������������������


git commit -am "Fix typo in error message"
# � Note: -a does NOT stage brand-new (untracked) files — use git add first

# �� Fix the last commit message (before pushing) ���������������������������


git commit --amend -m "Add Stripe payment integration with webhook support"

# �� Add a forgotten file to the last commit (before pushing) ���������������


git add src/stripe_config.py
git commit --amend --no-edit
# The last commit now includes stripe_config.py; same message

# �� Empty commit (useful for triggering CI) ��������������������������������


git commit --allow-empty -m "Trigger CI pipeline"

Writing great commit messages


� Good:
"Fix null pointer exception when user has no email"
"Add pagination to the /users endpoint"
"Refactor auth middleware to use JWT"

� Bad:
"fix"
"changes"
"WIP"
"asdfgh"

Common issues & fixes

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

# �� Full branch graph (the most useful view) ������������������������������


git log --oneline --graph --decorate --all
# * a3f4b2c (HEAD -> main) Add Stripe payment integration
# * 9d1e3a1 Fix null pointer in user lookup
# | * f1c2d3e (feature/auth) Add OAuth2 login
# | * e4a5b6c Start OAuth2 implementation
# |/
# * 7b2f0c8 Initial commit

# �� Find who changed a specific file ��������������������������������������


git log --oneline -- src/[Link]

# �� Find commits by message keyword ���������������������������������������


git log --oneline --grep="payment"

# �� See what changed in the last 3 commits ��������������������������������


git log -p -3

# �� Custom pretty format ���������������������������������������������������


git log --pretty=format:"%h %ad %an %s" --date=short
# a3f4b2c 2025-05-05 Priya Sharma Add Stripe payment integration
# 9d1e3a1 2025-05-04 Raj Kumar Fix null pointer in user lookup

Common issues & fixes

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

# �� See what is staged (about to be committed) �����������������������������


git diff --staged

# �� Compare two branches ���������������������������������������������������


git diff main..feature/payment
git diff main...feature/payment # triple-dot: only commits unique to feature

# �� Compare two commits ����������������������������������������������������


git diff 9d1e3a1 a3f4b2c

# �� 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

git branch -vv


# * main a3f4b2c [origin/main] Add Stripe payment integration
# feature/auth f1c2d3e [origin/feature/auth: ahead 2] Add OAuth2 login

# �� Create branches ��������������������������������������������������������


git branch feature/user-profile # create (you stay on current branch)
git checkout -b feature/user-profile # create AND switch to it (most common)
git switch -c feature/user-profile # modern equivalent

# �� Delete branches ��������������������������������������������������������


git branch -d feature/payment # safe delete (branch must be merged)
git branch -D feature/experiment # force delete (discard unmerged work)

# �� Delete a remote branch �������������������������������������������������


git push origin --delete feature/payment

14
# �� Rename the current branch ����������������������������������������������
git branch -m old-name new-name

# �� Rename local master → main ���������������������������������������������


git branch -m master main
git push origin -u main
git push origin --delete master

Common issues & fixes

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>

11. git checkout / git switch


What it does
Switches your working directory to a different branch or commit. git switch
(added in Git 2.23) is the modern, clearer replacement for branch switching; git
checkout does double duty (branches + files) and is still widely used.

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

# �� Create a new branch and switch to it ����������������������������������


git switch -c feature/dark-mode
git checkout -b feature/dark-mode # same thing

# �� Create a branch from a specific point ���������������������������������


git switch -c hotfix/login-crash origin/main
# or
git checkout -b hotfix/login-crash main

# �� View old code without changing anything (detached HEAD) ����������������


git checkout a3f4b2c
# HEAD is now at a3f4b2c Add Stripe payment integration
# (You are in 'detached HEAD' state — you can look around,
# but commits here won't belong to any branch unless you create one)

# To return to normal:
git switch main

# �� Save a detached HEAD experiment as a branch ���������������������������


git switch -c my-experiment # while in detached HEAD state

# �� Discard all uncommitted changes to a file (restore old syntax) ���������


git checkout -- src/[Link] # � destructive, no undo

Common issues & fixes

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

12. git merge


What it does
Integrates the history of one branch into another. Git creates a merge commit
that ties the two histories together (unless it can fast-forward). This preserves
the full context of when a branch existed.

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

Fast-forward vs. merge commit


Fast-forward (default when possible):
main: A → B
feature: B → C → D
After merge:
main: A → B → C → D (no merge commit — linear history)

Three-way merge (when histories diverged):


main: A → B → E
feature: B → C → D
After merge:
main: A → B → C → D → M (M = merge commit with two parents)

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

# �� Force a merge commit even on fast-forward (recommended for teams) ������


git merge --no-ff feature/payment
# Always produces a merge commit for clear history

# �� 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

# �� Dealing with merge conflicts �������������������������������������������


git merge feature/payment
# Auto-merging src/[Link]
# CONFLICT (content): Merge conflict in src/[Link]
# Automatic merge failed; fix conflicts and then commit the result.

git status # shows conflicted files

# Open src/[Link] — it looks like:


# <<<<<<< HEAD (your current branch, main)
# amount = [Link]['amount']
# =======
# amount = float([Link]['amount'])
# >>>>>>> feature/payment

# Edit the file to the correct version:


# amount = float([Link]('amount', 0))

git add src/[Link] # mark as resolved


git merge --continue # or just: git commit

# �� Abort if the merge is too messy right now ������������������������������


git merge --abort # returns everything to pre-merge state

Common issues & fixes

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

13. git rebase


What it does
Moves or “replays” commits from one branch onto the tip of another. The result
is a linear, clean history — as if you had started your work on top of the latest
changes instead of from an older point.

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

The golden rule


Never rebase public/shared commits. Rebase rewrites history.
If others have already pulled those commits, you’ll create divergent
histories and a world of pain.

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

# If conflicts arise during rebase:


# 1. Fix the conflicted files
# 2. git add <fixed-files>
# 3. git rebase --continue
# (repeat for each conflicting commit)

# �� Interactive rebase: clean up before opening a PR ����������������������


# You have 4 commits:
# d3c2b1a WIP: halfway done
# e4d3c2b Add payment function
# f5e4d3c Fix typo
# g6f5e4d Add tests for payment
#
git rebase -i HEAD~4
# Opens editor:
# pick d3c2b1a WIP: halfway done
# pick e4d3c2b Add payment function
# pick f5e4d3c Fix typo
# pick g6f5e4d Add tests for payment
#
# Change to:
# squash d3c2b1a WIP: halfway done ← squash into next commit
# pick e4d3c2b Add payment function
# fixup f5e4d3c Fix typo ← squash + discard this message
# pick g6f5e4d Add tests for payment
#
# Result: 2 clean commits instead of 4 messy ones

# Interactive rebase commands:


# pick = use commit as-is
# reword = use commit but edit the message
# edit = pause to amend the commit
# squash = meld into previous commit (keeps both messages)
# fixup = meld into previous commit (discards this message)
# drop = remove the commit entirely

# �� Rebase vs Merge: when to use which ������������������������������������


# Updating feature branch → use rebase (clean history)
# Bringing feature into main on a team → use merge (preserves context)

Common issues & fixes

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

14. git remote


What it does
Manages connections to remote repositories. origin is the conventional name
for the main remote (usually GitHub/GitLab) that is set automatically when
you git clone.

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)

# �� Open source workflow: fork + upstream ����������������������������������

21
# 1. Fork the repo on GitHub
# 2. Clone your fork
git clone git@[Link]:priya/[Link]
cd express

# 3. Add the original repo as 'upstream'


git remote add upstream git@[Link]:expressjs/[Link]

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)

# 4. Keep your fork up to date


git fetch upstream
git switch main
git merge upstream/main
git push origin main

# �� Switch from HTTPS to SSH �����������������������������������������������


git remote set-url origin git@[Link]:priya/[Link]

# �� Remove a remote ��������������������������������������������������������


git remote remove old-server

15. git fetch


What it does
Downloads commits, branches, and tags from a remote repository without
changing your working directory or current branch. It updates your
remote-tracking references (like origin/main) so you can inspect what changed
before deciding what to do.

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

# Review the changes before merging


git diff HEAD origin/main

# Now merge when you're ready


git merge origin/main

# �� Get a new remote branch that doesn't exist locally ��������������������


git fetch origin feature/new-dashboard
git switch feature/new-dashboard # now you can check it out

# �� Clean up deleted remote branches ��������������������������������������


git fetch --prune
# x [deleted] origin/feature/old-work

16. git pull


What it does
A shortcut for git fetch followed by git merge (or git rebase if configured).
It downloads remote changes and immediately integrates them into your current
branch.

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

# �� Pull with rebase (preferred for feature branches) ���������������������


git pull --rebase origin main
# Replays your local commits on top of the fetched commits
# No merge commit — linear history

# �� Make rebase the default for all pulls ���������������������������������


git config --global [Link] true
# Now 'git pull' always rebases

# �� Pull a specific branch �������������������������������������������������


git pull origin feature/payment:feature/payment

Common issues & fixes

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

17. git push


What it does
Uploads your local commits to a remote repository, making them available to
your team.

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

# �� Regular push �����������������������������������������������������������


git push

# �� Push was rejected (someone else pushed first) �������������������������


# error: failed to push some refs to 'origin'
# hint: Updates were rejected because the remote contains work that you do not have locally.
git pull --rebase # pull their changes, replay yours on top
git push # now it works

# �� Force push after a rebase (your own branch only!) ���������������������


git rebase -i HEAD~3 # cleaned up your local commits
git push --force-with-lease
# --force-with-lease fails if someone else pushed in the meantime (safer than --force)

# �� Delete a remote branch �������������������������������������������������


git push origin --delete feature/old-api

Common issues & fixes

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

18. git stash


What it does
Temporarily shelves (stashes) changes you’ve made but aren’t ready to commit,
so you can switch context and come back to them later.

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"

# Now your working directory is clean


git switch main
git switch -c hotfix/login-crash
# ... fix the bug, commit, push ...
git switch feature/dark-mode

26
# Restore your work
git stash pop
# Back where you were

# �� List all stashes �������������������������������������������������������


git stash list
# stash@{0}: On feature/dark-mode: dark mode: wip – halfway through CSS
# stash@{1}: On main: quick experiment

# �� Apply a specific stash without removing it �����������������������������


git stash apply stash@{1}

# �� Include untracked files in the stash ����������������������������������


git stash -u # or --include-untracked

# �� Turn a stash into a branch (when pop causes conflicts) �����������������


git stash branch feature/stash-rescue stash@{0}

Common issues & fixes

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}

19. git tag


What it does
Creates a named pointer to a specific commit, typically used to mark release
versions (v1.0.0, v2.3.1). Unlike branches, tags don’t move as you add commits.
Two types: - Lightweight tag: Just a name pointing to a commit - Annotated
tag: Full object with tagger name, date, message, and optional GPG signature
— use these for releases

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

# �� Tag an earlier commit ��������������������������������������������������


git log --oneline
# a3f4b2c Add Stripe payment integration ← should have been v1.0.0
# 9d1e3a1 Fix null pointer in user lookup
git tag -a v1.0.0 a3f4b2c -m "First stable release"

# �� List and inspect tags ��������������������������������������������������


git tag
git tag -l "v1.*" # filter by pattern
git show v1.0.0 # full tag details

# �� Semantic versioning pattern ��������������������������������������������


git tag -a v1.0.0 -m "Initial release"
git tag -a v1.0.1 -m "Patch: fix payment timeout"
git tag -a v1.1.0 -m "Feature: add dark mode"
git tag -a v2.0.0 -m "Breaking: new auth API"

# �� Delete a tag (locally + remotely) �������������������������������������


git tag -d v1.0.0-beta
git push origin --delete v1.0.0-beta

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.

The three modes

Flag HEAD moves? Staging area Working directory


--soft � Yes Unchanged (changes stay staged) Unchanged
--mixed (default) � Yes Reset (changes unstaged) Unchanged
--hard � Yes Reset Reset — changes are lost

Most dangerous: --hard (discards work)


Safest: --soft (keeps everything staged)

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

# �� Undo the last commit, unstage changes ���������������������������������


git reset HEAD~1
# Commit gone, changes are in working directory — you decide what to stage

# �� Completely discard the last 3 commits and their changes ����������������


git reset --hard HEAD~3
# � Those 3 commits and all their changes are gone locally

# �� Reset to a specific 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

# �� Unstage a file without losing changes ���������������������������������


git restore --staged src/[Link] # modern syntax
git reset HEAD src/[Link] # old syntax — same result

# �� Recover from a --hard reset using reflog ������������������������������


git reflog
# a3f4b2c HEAD@{0}: reset: moving to HEAD~3
# d8e9f0a HEAD@{1}: commit: the commit you want back
git reset --hard d8e9f0a # recovered!

Common issues & fixes

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

21. git revert


What it does
Creates a new commit that undoes the changes of a specific commit. Unlike
git reset, it doesn’t rewrite history — it adds to it. This makes it safe to use
on public/shared branches.

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

# �� Revert a specific earlier commit ��������������������������������������


git log --oneline
# a3f4b2c Deploy broken payment feature
# 9d1e3a1 Add payment UI
# 7b2f0c8 Add payment logic

git revert a3f4b2c


# New commit: "Revert "Deploy broken payment feature""
# a3f4b2c's changes are undone; 9d1e3a1 and 7b2f0c8 are untouched

# �� Revert without opening the editor �������������������������������������


git revert HEAD --no-edit

# �� Revert a merge commit ��������������������������������������������������


git log --oneline
# f9e8d7c Merge branch 'feature/payment' into main ← merge commit
git revert -m 1 f9e8d7c
# -m 1 means: keep "mainline parent 1" (main), undo the feature branch side

# �� Revert vs Reset: which to use? ����������������������������������������


# Commit not pushed yet → git reset (cleaner)
# Commit already pushed → git revert (safe)

Common issues & fixes

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

22. git restore


What it does
Discards changes in the working directory or unstages files from the staging area.
Introduced in Git 2.23 as a cleaner alternative to git checkout -- <file> and
git reset HEAD <file>.

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

# �� Discard all working directory changes ���������������������������������


git restore .

# �� Unstage a file (keep your edits in working dir) �����������������������


git restore --staged src/[Link]

# �� Restore a file to how it looked 3 commits ago �������������������������


git restore --source=HEAD~3 src/[Link]

# �� Restore a file to how it looked in a specific commit ������������������


git restore --source=9d1e3a1 src/[Link]

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

git log main --oneline | grep "fix"


# 9d1e3a1 Fix critical payment timeout ← the commit we want

git cherry-pick 9d1e3a1


# [release/1.x f2a1b0c] Fix critical payment timeout
# A new commit is created on release/1.x with the same changes

# �� Cherry-pick a range of commits ����������������������������������������


git cherry-pick 9d1e3a1^..a3f4b2c # from 9d1e3a1 to a3f4b2c inclusive

# �� Cherry-pick without auto-committing (to inspect first) ����������������


git cherry-pick --no-commit 9d1e3a1
git diff --staged # review changes
git commit -m "Backport: Fix critical payment timeout"

# �� Recover a commit made on the wrong branch ������������������������������


# Accidentally committed to main instead of feature/payment
git log --oneline main

33
# a3f4b2c Added payment form ← should be on feature/payment

git switch feature/payment


git cherry-pick a3f4b2c # copy it here

git switch main


git reset --hard HEAD~1 # remove it from main (it wasn't pushed)

Common issues & fixes

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

24. git bisect


What it does
Uses binary search to find the exact commit that introduced a bug. You
tell Git a “good” commit (before the bug) and a “bad” commit (after it), and
Git checks out commits halfway between, asking you to test each one. It finds
the culprit in O(log n) steps.

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

# Git checks out the midpoint commit. Test your app.


# If bug is present:
git bisect bad

# If bug is NOT present:


git bisect good

# Repeat 6-8 times; Git narrows down and then announces:


# a3f4b2c is the first bad commit
# Author: Raj Kumar <raj@[Link]>
# Date: Thu Apr 10 14:22:00 2025

# Return to your branch


git bisect reset

# �� Automated bisect with a test script �����������������������������������


# Create a script that exits 0 if "good", non-zero if "bad"
cat > test_regression.sh << 'EOF'
#!/bin/bash
python -m pytest tests/test_payment.py -q
EOF
chmod +x test_regression.sh

git bisect start


git bisect bad HEAD
git bisect good v2.0.0
git bisect run ./test_regression.sh
# Git finds the bad commit automatically — no manual testing needed
git bisect reset

25. git reflog


What it does
Shows a log of every position HEAD has been at — including after resets,
rebases, checkouts, and merges. It’s your ultimate safety net: even after a
hard reset, commits are usually recoverable here for 30–90 days.

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!

# �� Recover a deleted branch �����������������������������������������������


git branch -D feature/experiment # oops, deleted it

git reflog
# f1c2d3e HEAD@{3}: checkout: moving from feature/experiment to main
# f1c2d3e was the tip of feature/experiment

git branch feature/experiment f1c2d3e # recreate the branch

# �� Use with reset to explore what happened ��������������������������������


git reflog --date=relative
# a3f4b2c HEAD@{2 hours ago}: commit: Add payment form
# 9d1e3a1 HEAD@{3 hours ago}: commit: Start auth module
# 7b2f0c8 HEAD@{1 day ago}: clone: from [Link]/...

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

# �� See a file as it was 10 commits ago �����������������������������������


git show HEAD~10:src/[Link]

# �� See a file at a specific tag �������������������������������������������


git show v1.0.0:[Link]

# �� Quick summary of a commit ����������������������������������������������


git show --stat a3f4b2c

27. git blame


What it does
Shows who last modified each line of a file and in which commit. Essential for
understanding why code looks the way it does.

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(...)

# �� Blame just one section �������������������������������������������������


git blame -L 45,60 src/[Link]

# �� See the full commit for a blamed line ���������������������������������


git show 9d1e3a1 # see the full context of Raj's change

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 specific file


.env
[Link]

# Ignore all files with an extension


*.log
*.tmp
*.pyc

# Ignore a directory
node_modules/
__pycache__/
.venv/
dist/
build/

# Ignore a file only in the root


/[Link]

38
# Ignore files in any directory named logs
logs/

# Negate a rule (don't ignore this even if a previous rule would)


![Link]

# Ignore everything in a folder except one file


temp/*
!temp/[Link]

Examples
# �� Python project .gitignore ����������������������������������������������
cat .gitignore
# __pycache__/
# *.pyc
# *.pyo
# .env
# .venv/
# dist/
# build/
# *.egg-info/
# .pytest_cache/
# .coverage

# �� [Link] project .gitignore ��������������������������������������������


# node_modules/
# dist/
# .env
# .[Link]
# [Link]
# *.log

# �� Stop tracking a file that's already committed ��������������������������


# (e.g., you accidentally committed .env)
echo ".env" >> .gitignore
git rm --cached .env # remove from Git's index but keep the file
git commit -m "Remove .env from tracking"
git push

# �� Check why a file is ignored ��������������������������������������������


git check-ignore -v [Link]
# .gitignore:4:[Link] [Link]

# �� Get a ready-made .gitignore for your language ��������������������������


# Visit: [Link] or [Link]

39
curl -o .gitignore [Link]

Common issues & fixes

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

29. Real-World Workflows


Feature Branch Workflow (most common)
# �� Start a feature ��������������������������������������������������������
git switch main
git pull # ensure main is up to date
git switch -c feature/user-notifications

# �� Work, commit regularly �������������������������������������������������


git add src/[Link] tests/test_notifications.py
git commit -m "Add email notification service"
git add src/templates/
git commit -m "Add email templates for notifications"

# �� Stay up to date with main ����������������������������������������������


git fetch origin
git rebase origin/main # replay your commits on top of latest main

# �� Push and open a Pull Request ������������������������������������������


git push -u origin feature/user-notifications
# Open PR on GitHub

# �� After PR is approved: merge (done on GitHub or locally) ���������������


git switch main
git pull # gets the merged result
git branch -d feature/user-notifications # clean up
git push origin --delete feature/user-notifications

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

# After review + merge to main:


git switch main && git pull
git tag -a v1.0.1 -m "Hotfix: Fix divide-by-zero in payment"
git push origin v1.0.1

git branch -d hotfix/payment-crash

Keeping a Fork in Sync (open source contribution)


git remote add upstream [Link]
git fetch upstream
git switch main
git rebase upstream/main
git push origin main --force-with-lease # update your fork's main

30. Quick-Reference Cheat Sheet


Setup
git config --global [Link] "Name"
git config --global [Link] "email"
git init # new repo
git clone <url> # copy repo

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

Common Mistake Cheat Sheet

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

You might also like