Hey, future Git God. This is not your typical boring technical manual. This is a comic-book-style adventure where you are the hero, Git is the magic wand, and every chapter is a mission you must complete to level up. The story is told through the eyes of three friends from the Doraemon universe — Gian, Suneo, and Nobita — because every great coder started exactly where they are: confused, losing files, and wondering why their teammates keep emailing code over WhatsApp.
Each chapter follows the same playful structure. First, you get a Story Brief that sets up the problem. Then comes the Concept Unlock where the Git magic is explained in plain English with ASCII diagrams. After that, you suit up for a Mystery Mission — a hands-on lab framed as a coding detective story. Finally, you face a Scenario Quiz to test your real-world instincts, and a Career Tip box tells you why this skill matters in actual jobs and internships.
MEET CAPTAIN COMMIT
Your guide through this journey. Captain Commit has seen every Git disaster known to humanity — force-pushes to main, lost commits, merge conflicts that destroyed friendships — and lived to tell the tale. When you see Captain Commit, pay attention. He's about to drop a truth bomb that will save you hours of pain.
Here is the Skill Tree you will unlock as you progress. Each chapter grants you XP and unlocks the next level. Tick off each level as you complete its mission. By the end of this guide, you will have earned all six badges and the right to call yourself a Git God.
1
Git Newbie
+100 XP · Chapter 0-1 · Understand why Git exists and the difference between Git & GitHub
2
Commit Cadet
+200 XP · Chapter 2-4 · Install Git, master the three stages, run your first commits
3
Branch Boss
+250 XP · Chapter 5 · Create, switch, and navigate parallel universes with branches
4
Merge Master
+300 XP · Chapter 6 · Merge branches and resolve conflicts without crying
5
Remote Ranger
+350 XP · Chapter 7-8 · Push to GitHub, open PRs, collaborate like a pro
6
Git God
+500 XP · Chapter 9-10 + Final Boss · Time travel, rebase, and conquer any Git disaster
PRO TIP FROM CAPTAIN COMMIT
Don't read this guide like a novel. Read a chapter, close the book, open your terminal, and
actually do the mission. Git is a muscle. You cannot learn it by reading. You learn it by typing the commands, seeing the output, breaking things, and fixing them. Hands-on is the only way.
Before we learn what Git is, we need to feel the pain of not having Git. Meet our three heroes: Gian (the team lead, big and loud), Suneo (the rich kid with the fancy laptop), and Nobita (the lazy genius). They decided to build a college project together — a simple weather app. What could go wrong? Everything. Everything could go wrong.
STORY BRIEF
Gian opened his laptop on Monday, created a file called
app.txt, and wrote four lines of beautiful code. He saved it, closed the laptop, and went to sleep. On Tuesday, he opened the file, decided the code was buggy, and rewrote it. He saved again. On Wednesday, he realized Tuesday's code was worse than Monday's. He wanted Monday back. He pressed
Ctrl+Z. Nothing happened. The file was already saved. Monday's code was gone forever. Gian cried.
This is the first of six catastrophes that happen when you code without a version control system. Let's meet all six villains — they are the reasons Git was invented.
1
THE LOST WORK CURSE
You save a file, change it, save again. The old version is gone forever. Ctrl+Z only works for unsaved changes. Once you hit save, your previous work is overwritten and lost. Gian lost Monday's code this way. There is no time machine, no undo, no recovery.
2
THE MESSY FILENAME MONSTER
To avoid catastrophe #1, you start copying files before changing them. app.txt, app_v2.txt, app_final.txt, app_really_final.txt, app_final_USE_THIS_ONE.txt. Soon you have 47 files and no idea which one is the good version. Storage fills up. Sanity drops.
3
THE COLLABORATION IMPOSSIBILITY
Suneo wants to help Gian. Gian copies app.txt onto a pen drive, walks to Suneo's house, hands it over. Suneo edits, puts it back on the pen drive, walks back. Multiply by 100 changes. Now imagine Suneo lives in another country. Pen drives and WhatsApp file shares are not a real workflow.
4
THE HISTORY BLACK HOLE
There is no record of what changed, when, or why. Three weeks later, you wonder "why did I add that weird line in the login function?" There is no log. There is no history. There is only the present code, and your fading memory of why it looks the way it does.
5
THE OVERWRITE OVERLORD
Two teammates edit the same file at the same time. Whoever saves last wins. The other person's work is silently destroyed. There is no warning, no merge dialog, no conflict resolution. Just one teammate's code, living obliviously while the other teammate's hours of work vanish into the void.
6
THE LAPTOP CRASH APOCALYPSE
Gian's laptop falls. Hard drive dies. Every file — every version, every backup on the desktop, every app_final_v9.txt — is gone. There is no cloud backup. There is no recovery. The project is over. Gian's team fails the assignment. Nobita laughs. Suneo cries.
These six villains are why every software company in the world uses version control. Version control is a system that tracks every change to your code, lets you travel back in time, enables real collaboration, and backs up your work to the cloud. Git is the most popular version control system in the world. GitHub is the most popular cloud platform for hosting Git repositories. Together, they are the dynamic duo that defeats all six villains.
+--------------------------------------------------+
| THE CHAOS WITHOUT GIT |
+--------------------------------------------------+
| |
| Gian's Laptop Suneo's Laptop |
| +-----------+ +-----------+ |
| | app.txt | | app.txt | |
| | app_v2.txt| | app_v3.txt| |
| | app_final | | real_final| |
| +-----+-----+ +-----+-----+ |
| | | |
| | pen drive / | |
| | WhatsApp / | |
| | email dance | |
| v v |
| +-------------------------+ |
| | WHICH VERSION IS | |
| | THE LATEST?!?! | |
| | (nobody knows) | |
| +-------------------------+ |
| |
| Nobita's Laptop: crashed. Files gone. Done. |
+--------------------------------------------------+
FIG 0.1 · The pre-Git nightmare
WHY THIS MATTERS IN INDUSTRY
In any real software job — at a startup, at Google, at a 3-person freelance team — version control is non-negotiable. There is no company on Earth that lets you email code files to your teammates. When you walk into an interview and they ask "do you know Git?", they are not asking if you've heard of it. They are asking if you can clone a repo, branch, commit, push, open a PR, and resolve a merge conflict without panicking. Mastering Git is the difference between getting hired and getting ghosted.
THE LOST CODE MYSTERY
Captain Commit has summoned you. A first-year student named Priya lost three hours of code yesterday because she overwrote her file and had no backup. Your mission: investigate the crime scene and report back on which of the six villains caused the disaster — and how Git could have saved her.
Open a text editor and create a file called disaster_report.txt
Write down all 6 villains from this chapter in your own words
For each villain, write one sentence: "Git could have prevented this by ____"
Save the file in a folder called git_and_github_nyc on your Desktop
This folder will become your training ground for the rest of the guide
+100 XP · UNLOCKED: Git Newbie badge · You now see the matrix of why Git exists
Q1. Your teammate Rahul emails you a zip of his code, you make changes, email it back. He makes his own changes and emails you again. You realize you've lost some of your edits. Which villain is responsible?
A. The Lost Work Curse
B. The Overwrite Overlord
C. The Collaboration Impossibility
D. The History Black Hole
Answer: C — The Collaboration Impossibility. The email-zip dance is a broken workflow. A version control system lets both of you work on the same codebase simultaneously without emailing files back and forth.
Q2. You're working on a bug, you change 5 files, save them, then realize you've made things worse. You want yesterday's version back. What happens without Git?
A. Press Ctrl+Z 50 times to undo
B. The old versions are gone forever — they were overwritten
C. The OS auto-backs-up everything, just check the recycle bin
D. Email your teammate, they probably have a copy
Answer: B — Without Git, saved changes overwrite old versions. Ctrl+Z only works for unsaved changes. The recycle bin doesn't help because you didn't delete the file — you modified it. Git solves this by saving snapshots you can return to anytime.
Q3. Which statement best describes the role of version control?
A. It's a backup tool that copies files to the cloud
B. It's a system that tracks every change, enables time travel, and supports team collaboration
C. It's an email replacement for sharing code files
D. It's a fancy name for saving files with version numbers like v1, v2, v3
Answer: B — Version control is much more than backup. It tracks history, allows branching and merging, enables collaboration, and lets you time-travel to any past state. The v1/v2/v3 file naming is the broken system Git was invented to replace.
Now that you have felt the pain, let's meet the heroes that will rescue you. Git and GitHub are two different things — but most beginners use the words interchangeably and confuse everyone, including themselves. Let's fix that forever, right now.
What is Git? The Local Time Machine
Git is a distributed version control system (DVCS). That's a fancy way of saying: it's a tool that lives on your computer and tracks every change you make to your code, without you having to copy-paste files or rename them with version numbers. Git runs entirely on your laptop — no internet required. You can use it on a plane, in a cave, in your grandma's village with no WiFi. It just works, locally.
Let's break down the definition. Distributed means every developer has a full copy of the entire project history on their own machine. There's no central server you must beg for permission. You can commit, branch, merge, and time-travel entirely offline. Version control means Git stores snapshots of your project at every point you tell it to — and you can travel back to any snapshot at any time, without copying files or wasting storage. Git is smart: it stores only the differences between snapshots, not full copies, so even huge projects stay small.
STORY BRIEF
Gian used Git on his laptop. He wrote code, ran
git commit, and Git saved a snapshot called "Version 1" — without copying any file. He changed the code, committed again — "Version 2". Then again — "Version 3". All three versions exist on his laptop, but his folder has only one
app.txt. No
app_v2.txt. No
app_final.txt. No storage bloat. No filename confusion. When Gian wanted Version 1 back, Git handed it over in milliseconds. Gian stopped crying.
What is GitHub? The Cloud Collaboration Hub
GitHub is a cloud platform that hosts your Git repositories online. Think of Git as the engine in your car, and GitHub as the parking lot where you and your friends leave your cars so everyone can see them, work on them together, and merge their improvements. GitHub runs on the internet — you push your local commits up to GitHub, and your teammates pull them down to their laptops.
Here's the key insight: Git works alone, on your laptop. GitHub is for when you want to collaborate. If you're a solo developer writing code on a desert island, Git is enough. The moment you want Suneo (who lives in another city) to edit your code, you need a central place to exchange commits — and that place is GitHub. GitHub also gives you a beautiful web UI to view your code, browse commit history, open pull requests, manage issues, and showcase your portfolio to recruiters.
+----------------------------------------------------------+
| GIT vs GITHUB |
+----------------------------------------------------------+
| |
| YOUR LAPTOP (offline, local) |
| +------------------+ |
| | Git installed | <-- tracks every change |
| | Local repo | on your machine |
| | .git folder | works offline |
| +--------+---------+ |
| | |
| | git push ^| git pull |
| | || git fetch |
| v v| |
| +----------------------+ |
| | GITHUB (online) | <-- cloud hosting |
| | Remote repo | team collaboration |
| | Pull Requests | portfolio showcase |
| | Issues, Wiki | backup of your code |
| +----------------------+ |
| |
| Suneo's Laptop <-----> GitHub <-----> Nobita's Laptop |
| (everyone pulls & pushes through GitHub) |
+----------------------------------------------------------+
FIG 1.1 · Git is local, GitHub is the cloud
The Differences That Confuse Beginners
| Feature | Git | GitHub |
| What is it? | A version control tool (software) | A cloud platform (website service) |
| Where does it live? | Installed on your laptop | Hosted on the internet at github.com |
| Internet needed? | No — works fully offline | Yes — it's a cloud service |
| Who made it? | Linus Torvalds (2005, same guy who made Linux) | Tom Preston-Werner and others (2008), now owned by Microsoft |
| Main job | Track changes, commit, branch, merge locally | Host repos, enable collaboration, PRs, code review |
| Cost | Free, open-source, forever | Free for public & private repos (free tier) |
| Alternatives | Mercurial, SVN, Bazaar | GitLab, Bitbucket, Gitea, Codeberg |
| Can you use one without the other? | Yes — Git works fine alone | No — GitHub requires Git (it hosts Git repos) |
THE GOLDEN RULE
If you remember nothing else from this chapter, remember this:
Git is the tool. GitHub is the cloud service that uses Git. Git can exist without GitHub. GitHub cannot exist without Git. When in doubt, ask yourself: "Does this need internet?" If yes → GitHub. If no → Git.
Why Both? The Superhero Duo
You need both because they solve different problems. Git alone solves problems 1, 2, 4, and 5 from Chapter 0 — it tracks history (defeating the History Black Hole), lets you snapshot without copying files (defeating the Messy Filename Monster), prevents overwrites by detecting conflicts (defeating the Overwrite Overlord), and lets you travel back in time (defeating the Lost Work Curse). But Git alone can't solve problems 3 and 6 — Collaboration Impossibility and Laptop Crash Apocalypse. For those, you need a cloud backup where teammates can pull and push code. That's GitHub.
Together, Git + GitHub defeat all six villains. Your local Git tracks everything offline. You periodically push your commits to GitHub for backup and team access. If your laptop dies, you just clone your repo from GitHub onto a new laptop — every commit, every branch, every line of history, restored in seconds. If Suneo wants to help, he clones your GitHub repo, makes changes locally with his own Git, and pushes back. No pen drives. No WhatsApp. No tears.
WHY THIS MATTERS IN INDUSTRY
Walk into any software company on Earth — Google, Amazon, a 5-person startup, your college's coding club — and ask "do you use Git and GitHub?" The answer will be "yes" 99% of the time (the 1% uses GitLab or Bitbucket, which are essentially the same concept). Your GitHub profile is your
public portfolio. Recruiters look at it. Hiring managers browse your repos. A green contribution graph, clean commit history, and well-written PR descriptions can land you an interview before you even speak to a human. Git + GitHub is not optional. It is the oxygen of the software industry.
THE VCS DETECTIVE
Captain Commit has received a confused message from a first-year student: "I installed GitHub on my laptop but I can't commit offline. Is Git broken?" Your mission: diagnose the misunderstanding and write a one-paragraph explanation that even Nobita could understand.
Open disaster_report.txt from Mission 1
Add a new section titled "VCS Detective Findings"
Explain in 3-4 sentences: Git vs GitHub, which one is installed locally, which one needs internet
Bonus: search the web for "Linus Torvalds Git 2005" and write one fun fact
Save the file. You'll need it for the next chapter's setup
+50 XP BONUS · Skill earned: Explain Git vs GitHub to a 5-year-old
Q1. You're on a 12-hour flight with no WiFi. You want to keep working on your code and tracking changes. Which statement is true?
A. You can't do anything — GitHub needs internet
B. You can commit, branch, and merge locally with Git; push to GitHub after landing
C. You must wait until WiFi is available to write any code
D. You can push to GitHub using airplane mode
Answer: B — Git is fully functional offline. You commit, branch, merge, and time-travel locally. When you land and reconnect, you push all your commits to GitHub in one go. This is the "distributed" in DVCS — every developer has the full history on their machine.
Q2. Your friend says "I don't need Git, I just use GitHub." What's wrong with this statement?
A. Nothing — GitHub replaces Git entirely
B. GitHub is just a hosting platform; you still need Git installed locally to commit, branch, and merge
C. You can use GitHub's web editor and never need Git, so the friend is right
D. Git and GitHub are the same thing, so it doesn't matter
Answer: B — GitHub hosts Git repositories, but to actually work with code on your laptop — commit, branch, merge, resolve conflicts — you need Git installed locally. GitHub's web editor is fine for tiny fixes, but real development requires local Git. (Note: GitHub did add a web-based editor and Codespaces, but those still use Git under the hood.)
Q3. Which problem can GitHub solve that Git alone cannot?
A. Tracking changes to your code
B. Branching and merging
C. Backing up your code offsite and enabling collaboration with remote teammates
D. Viewing commit history
Answer: C — Git alone is local-only. If your laptop crashes, your Git repo crashes with it. GitHub provides the offsite cloud backup and the central hub that remote teammates can push to and pull from. The other three options (tracking, branching, history) are all Git features that work without GitHub.
Theory time is over. Now we install Git, set up your terminal, configure your identity, and verify everything works. This chapter is short on story and long on hands-on. Open your laptop. Follow every step. Do not skip. If you skip, the next chapters will not work, and you will be sad.
Step 1: Install Git
Git is just a piece of software. You download it, install it, and it lives on your laptop forever. The official source is git-scm.com. The website auto-detects your operating system and offers the right installer. Here's how to install on each OS:
For Windows (90% of you)
# 1. Go to https://git-scm.com
# 2. Click "Download for Windows"
# 3. Run the .exe installer
# 4. Click Next > Next > Next (default settings are fine)
# 5. Finish. Search "Git Bash" in your start menu.
# Verify installation in Git Bash:
git --version
git version 2.43.0.windows.1 # any 2.x version is fine
For macOS
# Option A: Using Homebrew (recommended)
brew install git
# Option B: Download from https://git-scm.com
# Click "Download for Mac" and run the .dmg
# Verify installation:
git --version
git version 2.43.0
For Linux (Debian/Ubuntu)
sudo apt update
sudo apt install git -y
# Verify installation:
git --version
git version 2.43.0
WHY GIT BASH ON WINDOWS?
Git Bash is a Linux-style terminal that ships with Git for Windows. Why use it instead of PowerShell or Command Prompt? Because Git was born on Linux, and some of its commands (and Unix utilities like
ls,
pwd,
cat) only work properly in a Bash shell. Git Bash gives you the same experience on Windows that Linux/Mac users enjoy. Throughout this guide, we'll use Git Bash.
Windows users: always open Git Bash, not cmd or PowerShell.
Step 2: First-Time Configuration
Before you can make any commits, Git needs to know who you are. Every commit you ever make will be stamped with your name and email. This is how Git tracks who did what. You only configure this once per laptop — Git remembers it forever. Run these two commands in Git Bash (or Terminal on Mac):
# Set your name (use the name you want on your commits)
git config --global user.name "Your Real Name"
# Set your email (use the SAME email as your GitHub account)
git config --global user.email "your.email@example.com"
# Optional: set your default editor
git config --global core.editor "code --wait"
# Verify your config:
git config --global user.name
Your Real Name
git config --global user.email
your.email@example.com
CRITICAL: USE YOUR GITHUB EMAIL
When you create your GitHub account (next chapter), use the
exact same email here. If your local Git email doesn't match your GitHub email, your commits won't be linked to your GitHub profile, and your contribution graph won't show green squares. Many beginners get this wrong and wonder why their hard work isn't showing up on GitHub. Use the same email. Always.
Step 3: Install VS Code (Your Code Editor)
VS Code is the most popular code editor in the world, free, made by Microsoft, and has built-in Git support. You don't strictly need it — any text editor works — but VS Code makes Git beautifully visual. Download it from code.visualstudio.com and install with default settings. Once installed, open VS Code, and you can open the integrated terminal with Ctrl + ` (backtick, the key above Tab).
Step 4: Verify Everything Works
Open Git Bash (Windows) or Terminal (Mac/Linux) and run the magic verification command. If you see a version number, Git is installed correctly. If you see "command not found", something went wrong.
git --version
git version 2.43.0 # Success! Git is installed.
# If you see this instead:
bash: git: command not found
# → Git is not installed. Re-do Step 1.
# Check your config one more time:
git config --list
user.name=Your Real Name
user.email=your.email@example.com
core.editor=code --wait
Troubleshooting Common Install Issues
| Error | Cause | Fix |
| bash: git: command not found | Git not installed, or terminal needs restart | Reinstall from git-scm.com; close & reopen terminal |
| 'git' is not recognized as an internal or external command | Git not in PATH (Windows) | Reinstall Git and check "Add to PATH" option |
| Permission denied (publickey) | SSH key not set up (later chapter) | Will fix in Chapter 7 when we cover SSH |
| fatal: not in a git repository | You ran a Git command outside a repo | cd into your project folder first, then git init |
| Please tell me who you are | You haven't set user.name and user.email | Run the two config commands from Step 2 |
WHY THIS MATTERS IN INDUSTRY
Every onboarding at every tech company starts with: "install Git, clone our repo, build the project". If you can't install Git and verify it works in under 10 minutes, you'll struggle on day one of your first job. This chapter is the foundation of every future paycheck. Get it right now, and you'll never have to think about it again.
THE SETUP SAGA
A shadowy figure named "The Phantom Coder" has been leaving commits with the name "unknown" and email "none@none.com". Recruiters cannot identify them. Captain Commit needs you to set up your Git identity properly so the world knows who you are.
Open Git Bash (Windows) or Terminal (Mac/Linux)
Run git --version and screenshot the output
Run git config --global user.name "Your Name" with your real name
Run git config --global user.email "your.email@example.com"
Verify with git config --list — both values should appear
Open VS Code, press Ctrl+` to open the terminal, and run git --version there too
+100 XP · Skill earned: Git is installed and configured · You are no longer anonymous
Q1. You installed Git on Windows but when you type git --version in Command Prompt, you see "'git' is not recognized". What's the most likely fix?
A. Reinstall Windows
B. Open Git Bash instead of Command Prompt, or reinstall Git with "Add to PATH" checked
C. Git doesn't work on Windows, switch to Linux
D. Type "Git" with a capital G
Answer: B — On Windows, Git works perfectly in Git Bash (which ships with Git). If you want it in Command Prompt or PowerShell, you must check "Add Git to PATH" during installation. Reinstall with that option, or just use Git Bash which always works.
Q2. Why must your git config user.email match your GitHub account email?
A. For security — Git verifies your email each commit
B. So GitHub can link your commits to your profile and show green contribution squares
C. It doesn't matter — Git and GitHub don't share data
D. To avoid paying for GitHub premium
Answer: B — GitHub uses your commit email to attribute commits to your profile. If they don't match, your commits still get pushed, but they won't appear on your contribution graph or profile activity. Many beginners lose months of "green squares" because of this mismatch. Use the same email everywhere.
Q3. You set user.name and user.email with the --global flag. What does --global mean?
A. It pushes your config to GitHub
B. The setting applies to every Git repo on your laptop, not just the current one
C. It makes your commits visible worldwide
D. It requires internet to function
Answer: B — --global writes to ~/.gitconfig, which applies to every repo on your laptop. Without --global, the setting only applies to the current repo (stored in .git/config). Most users want global config so they don't have to re-set their identity in every project.
This is the most important chapter in the entire guide. If you understand the three stages of Git, you understand Git. Everything else — commits, branches, merges, conflicts — is just a variation of these three stages. Get this right, and the rest of Git feels natural. Get this wrong, and you'll spend years confused about why git add and git commit are two separate commands.
STORY BRIEF
Captain Commit appears in a puff of yellow smoke. "Listen carefully," he says. "Every Git repo has three zones, like a stadium has three areas: the parking lot, the locker room, and the field. Files move from one zone to the next. Understand the zones, and you understand Git." He snaps his fingers. A diagram appears in the air. Your eyes widen. Everything makes sense now.
The Three Stages
Every Git repository has three conceptual zones where your files live. They are: the Working Directory, the Staging Area, and the Repository. Files move from one zone to the next as you decide what to track and what to save. Here's what each zone does.
1. Working Directory (The Parking Lot)
This is the folder on your laptop where you actually write code. Every file you see in VS Code, every file in your project folder — that's the working directory. Git can see these files, but it is not tracking them yet. Files in the working directory are called untracked until you tell Git to start paying attention to them. Think of it like a parking lot: lots of cars, but nobody has been registered for the race yet.
2. Staging Area (The Locker Room)
When you run git add, you move a file from the working directory into the staging area. The staging area is like a locker room — files here are registered for the next snapshot, but the snapshot hasn't been taken yet. You can add more files, remove files, or change your mind before the big moment. The staging area lets you curate exactly which changes will be in your next commit, instead of just saving everything blindly.
3. Repository (The Stadium Field)
When you run git commit, Git takes a snapshot of everything in the staging area and permanently stores it in the repository. The repository is the stadium field — the official record book. Once a commit is made, it's locked in history forever (well, almost — Chapter 9 covers undoing). The staging area is cleared, ready for the next round of changes. The working directory still has your files, but the snapshot is safely stored.
+----------------------------------------------------------+
| THE THREE STAGES OF GIT |
+----------------------------------------------------------+
| |
| WORKING DIR STAGING AREA REPOSITORY |
| (parking lot) (locker room) (the field) |
| |
| +-----------+ +-----------+ +-----------+ |
| | app.txt | git | app.txt | git | app.txt | |
| | app2.txt | add --> | (staged) |commi| (saved!) | |
| | app3.txt | | app2.txt |t -->| | |
| | (untrack) | | (staged) | | commit #1 | |
| +-----------+ +-----------+ +-----------+ |
| |
| Files you're Files you've Permanent |
| editing right now marked for the snapshots |
| Git sees but next snapshot stored in |
| doesn't track yet (curated zone) history |
| |
| STATUS: ?? STATUS: A STATUS: saved |
+----------------------------------------------------------+
FIG 3.1 · The sacred three-stage flow
The U / A / M Markers — Git's Status Codes
When you run git status (which you'll do a thousand times), Git shows you markers next to each file. These single letters tell you what state each file is in. Master these markers, and you'll never be confused about what Git is doing.
| Marker | Name | Meaning | What to do |
| ?? | Untracked | File exists in working dir, Git doesn't know about it yet | git add to start tracking |
| A | Added | New file in staging area, ready for first commit | git commit to save |
| M | Modified | Tracked file has been changed since last commit | git add then git commit |
| D | Deleted | Tracked file was deleted from working dir | git add (yes, add) to stage the deletion |
| R | Renamed | Tracked file was renamed | git add to stage the rename |
| (blank) | Clean | No changes — working dir matches last commit | Nothing to do, keep coding |
THE SHOPPING CART ANALOGY
Think of the staging area as a shopping cart in a supermarket. You walk the aisles (working directory), picking items and tossing them in the cart (git add). When you reach the checkout, you pay for everything in the cart (git commit). The cart lets you batch related items together — you don't pay for each item individually, and you can put an item back on the shelf if you change your mind (git reset HEAD <file>).
Why Two Steps? Why Not Just Save?
Beginners often ask: "Why do I need git add AND git commit? Why not just one command that saves everything?" Great question. The answer is control. Imagine you've changed 5 files: 3 are for a new feature, 2 are unrelated bug fixes. With the staging area, you can stage only the 3 feature files and commit them as "Add login feature", then stage the 2 bug-fix files and commit them as "Fix navbar overflow". Two clean, logical commits. Without staging, you'd be forced to commit all 5 files together as one messy "stuff I changed today" commit. Staging = curation = better history.
WHY THIS MATTERS IN INDUSTRY
Senior engineers judge each other by the quality of their commit history. Clean, atomic commits ("Fix off-by-one in loop" / "Refactor auth module" / "Update README") show you understand your own changes. Messy commits ("stuff", "fixes", "wip", "final final final") scream junior. The staging area is your tool for crafting beautiful commits. Use it. Love it. Recruiters will read your commit history before they read your resume.
THE STAGING SLEUTH
Captain Commit has discovered a crime scene: a junior dev ran git commit without staging any files first. Nothing was saved. The dev is in tears. Your mission: investigate why staging matters by drawing the three stages yourself.
Open your git_and_github_nyc folder from Mission 1
Create a new file called stages_map.txt
Draw the three stages (Working / Staging / Repo) in ASCII art
Label what happens at each stage and which command moves files between them
Write one paragraph: "Why git add and git commit are separate commands"
Save. We'll actually use these commands in the next chapter.
+150 XP · Skill earned: Visualize Git's three stages in your sleep · You'll never confuse add and commit again
Q1. You created a new file login.py and ran git status. The file shows with ?? next to it. What does this mean?
A. Git is confused and there's a syntax error
B. The file is untracked — Git sees it but isn't tracking changes to it yet
C. The file is staged and ready to commit
D. The file has been deleted
Answer: B — ?? means untracked. The file exists in your working directory, but Git has never been told to track it. Run git add login.py to start tracking it (it'll move to the staging area, marked with A for Added).
Q2. You ran git add app.txt then changed your mind and edited the file again. What's the state now?
A. The new changes are automatically staged
B. The staging area has the OLD version; the working directory has the NEW version — both have changes
C. The file is now in the repository
D. Git will throw an error
Answer: B — The staging area still has the version you staged. The working directory has your new edits. git status will show the file as both staged AND modified. You must git add again to update the staging area with the latest version. This trips up many beginners.
Q3. What is the purpose of the staging area? Why not just commit changes directly?
A. It's a backup zone in case your laptop crashes
B. It lets you curate which changes go into a commit, so commits can be clean and logical
C. It's where GitHub pulls from
D. It's required by law
Answer: B — Staging = curation. You might change 5 files for 2 different reasons. Staging lets you commit 3 files as "feature X" and 2 files as "fix Y", producing a clean history. Without staging, every commit would be a messy dump of all your current changes. This is the #1 reason Git separates add from commit.
Now we type our first real Git commands. Open Git Bash. Navigate to the git_and_github_nyc folder you created in Mission 1. We will learn the seven foundational commands that 90% of Git usage is built on. By the end of this chapter, you will have made your first commit. Captain Commit is proud already.
Command 1: pwd — Where Am I?
pwd stands for Print Working Directory. It tells you exactly where you are in your file system. Whenever you open a terminal, you're "in" some folder. pwd reveals which one. This is critical because Git commands only work if you're inside a Git repository.
pwd
/c/Users/yourname/Desktop/git_and_github_nyc
# You are inside the git_and_github_nyc folder. Perfect.
Command 2: cd — Change Directory
cd stands for Change Directory. It moves you into a different folder. You can use relative paths (from current location) or absolute paths (full path from root).
# Go into a subfolder called "project"
cd project
# Go up one level (to parent folder)
cd ..
# Go to your Desktop (Mac/Linux)
cd ~/Desktop
# Go to your Desktop (Windows Git Bash)
cd /c/Users/yourname/Desktop
# Go back to previous directory
cd -
Command 3: ls — List Files
ls lists the files and folders in your current directory. Add the -a flag to see hidden files (files starting with a dot, like .git).
ls
disaster_report.txt stages_map.txt
# With -a flag, hidden files appear (those starting with .)
ls -a
. .. .git disaster_report.txt stages_map.txt
# .git is hidden — that's where Git stores its magic
Command 4: git init — Birth of a Repository
This is where the magic begins. git init turns a normal folder into a Git repository. It creates a hidden .git folder inside your directory. That .git folder is the brain — it stores every commit, every branch, every piece of history. You only run git init once per project. After that, Git is watching.
# Make sure you're inside the project folder
pwd
/c/Users/yourname/Desktop/git_and_github_nyc
# Initialize Git in this folder
git init
Initialized empty Git repository in /c/Users/.../git_and_github_nyc/.git/
# Verify .git folder was created
ls -a
. .. .git disaster_report.txt stages_map.txt
# ^^^ .git folder now exists. Git is alive!
NEVER DELETE THE .git FOLDER
The
.git folder is your entire project history. Every commit, every branch, every snapshot — all in there. If you delete it, your repo becomes a normal folder again, and all history is lost forever. Don't touch it. Don't edit files inside it. Don't commit it. Just let it do its job in peace.
Command 5: git status — Your Best Friend
If you remember only one command from this entire guide, let it be git status. It tells you everything: what files are untracked, what's staged, what's modified, what branch you're on. Run it before every commit. Run it when confused. Run it when bored. git status is your Git GPS.
git status
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
disaster_report.txt
stages_map.txt
nothing added to commit but untracked files present (use "git add" to track)
# Translation:
# - You're on the "main" branch (default)
# - No commits yet (this is a fresh repo)
# - 2 untracked files (Git sees them but isn't tracking)
# - Nothing is staged for commit yet
Command 6: git add — Stage Files
git add moves files from the working directory into the staging area. You can add one file, multiple files, or everything at once.
# Stage a single file
git add disaster_report.txt
# Stage multiple files (space-separated)
git add disaster_report.txt stages_map.txt
# Stage ALL files in current directory (the dot means "everything here")
git add .
# Verify staging
git status
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: disaster_report.txt
new file: stages_map.txt
# ^^^ Files now show as "new file:" under "Changes to be committed"
# They are STAGED. Ready for the commit hammer.
THE MAGIC DOT (.)
In Bash, the dot
. means "the current directory". So
git add . means "add every change in the current directory". This is the most common form of
git add — you'll use it 95% of the time. The other 5% is when you want to stage only specific files for a clean, atomic commit.
Command 7: git commit — Save the Snapshot
This is the moment of truth. git commit takes everything in the staging area and permanently saves it as a snapshot in your repository. Every commit needs a message — a short description of what changed. Use the -m flag (short for "message") to write your commit message inline.
# Make your first commit with a message
git commit -m "Initial commit: add disaster report and stages map"
[main (root-commit) c9c570f] Initial commit: add disaster report and stages map
2 files changed, 45 insertions(+)
create mode 100644 disaster_report.txt
create mode 100644 stages_map.txt
# Translation:
# - "main" = the branch you're on
# - "root-commit" = first commit ever in this repo
# - "c9c570f" = the commit's unique ID (hash)
# - 2 files were added, 45 lines total
# Check status after commit
git status
On branch main
nothing to commit, working tree clean
# ^^^ "working tree clean" = nothing pending, all saved!
Command 8: git log — View History
git log shows you the entire commit history of your repository. Each commit has a unique hash (ID), author, date, and message. This is your time machine's directory — every snapshot ever taken, listed in reverse chronological order.
git log
commit c9c570f3a2b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8 (HEAD -> main)
Author: Your Name <your.email@example.com>
Date: Mon Jan 15 10:30:00 2026 +0530
Initial commit: add disaster report and stages map
# Press 'q' to exit the log viewer if it doesn't return to prompt
# Compact one-line view (very useful):
git log --oneline
c9c570f (HEAD -> main) Initial commit: add disaster report and stages map
Writing Good Commit Messages
Commit messages are how you communicate with your future self and your teammates. A good message answers "why was this change made?" in one line. Bad commit messages are vague ("stuff", "fixes", "wip"). Good ones are specific and use the imperative mood ("Add login form" not "Added login form").
| Bad Commit Message | Good Commit Message |
| stuff | Add user registration form with email validation |
| fixes | Fix off-by-one error in pagination loop |
| wip | WIP: refactor auth middleware (do not merge) |
| final | Update README with installation steps |
| asdf | Remove unused import from utils.py |
| commit | Handle empty input in search function |
| changes | Style navbar with new color palette |
WHY THIS MATTERS IN INDUSTRY
When a senior engineer reviews your pull request, the first thing they look at is your commit history. Clean, atomic commits with clear messages signal "this person thinks before they code". Messy commits signal "this person types randomly and hopes for the best". The seven commands you just learned —
pwd,
cd,
ls,
git init,
git status,
git add,
git commit,
git log — are 80% of what professional developers type every day. You are no longer a beginner. You are a Commit Cadet.
THE FIRST COMMIT RITUAL
Captain Commit has guided you to the sacred ritual. The folder is ready. The files are waiting. Your mission: perform the eight-command dance and make your very first Git commit. This is the moment you transform from a person-who-codes into a version-controlled developer.
Open Git Bash (or VS Code terminal with Ctrl+`)
cd into your git_and_github_nyc folder
Run pwd to confirm your location
Run git init to initialize the repo (if not already done)
Run git status — you should see untracked files
Run git add . to stage all files
Run git commit -m "Initial commit: add disaster report and stages map"
Run git log --oneline to see your first commit in history
+200 XP · UNLOCKED: Commit Cadet badge · You have officially entered the version-controlled world · Captain Commit salutes you
Q1. You run git commit -m "fix" but get the error "nothing to commit, working tree clean". What did you forget?
A. You forgot to push to GitHub
B. You forgot to git add your changes first — there's nothing staged
C. You need to install Git again
D. The commit message is too short
Answer: B — "nothing to commit, working tree clean" means the staging area is empty. You changed files but never ran git add. Remember the three stages: Working → Staging → Repo. git add moves files from Working to Staging; git commit moves them from Staging to Repo. You can't commit what you haven't staged.
Q2. Which command shows you the entire history of commits in your repo?
A. git history
B. git log
C. git show
D. git list
Answer: B — git log lists every commit in reverse chronological order. Add --oneline for a compact view (one commit per line). Add --graph for a visual branch tree. Add --author="name" to filter by author.
Q3. You accidentally ran git init inside your Documents folder. Now Git is tracking everything. How do you undo this?
A. Run git undo init
B. Delete the hidden .git folder inside Documents — the folder becomes normal again
C. Reinstall Git
D. You can't undo git init
Answer: B — git init just creates a .git folder. Delete that folder (use ls -a to see it first, since it's hidden), and the directory becomes a normal folder again. No history was created unless you committed. On Windows: rmdir /s .git in cmd, or just delete it via File Explorer after enabling "show hidden files".
Imagine you're watching a Spider-Man movie. There's the main timeline where Peter Parker is friendly neighborhood Spidey. Then there's a parallel universe where Gwen Stacy got the bite instead. And another where Miles Morales is the hero. They all exist simultaneously, independently, until something causes them to collide. Git branches are exactly this — parallel universes of your codebase. You can create a new timeline, experiment wildly, and if it works, merge it back into the main timeline. If it fails, you just abandon that universe and walk away.
STORY BRIEF
Gian was working on the weather app's login feature directly in main. Halfway through, Suneo asked him to also fix a small bug in the home page. Gian switched files, made the fix, and committed — mixing login-WIP code with the bug fix in one messy commit. Then his login broke, his bug fix introduced a new bug, and main was a disaster. Captain Commit appeared: "You need to learn branches, Gian. They are parallel universes where you can experiment without destroying the main timeline."
What is a Branch?
A branch is a parallel line of development. When you create a branch, Git makes a new pointer to your current commit. From that point, the new branch can diverge — new commits on the new branch don't affect main, and new commits on main don't affect the new branch. It's like forking a road: two paths, same starting point, different destinations. The default branch in modern Git is called main (formerly master).
+----------------------------------------------------------+
| BRANCHES = PARALLEL UNIVERSES |
+----------------------------------------------------------+
| |
| main: A---B---C---D---E---F---G---H---I (HEAD) |
| \ |
| feature/login: X---Y---Z---W |
| |
| - main has commits A,B,C,D,E,F,G,H,I (9 commits) |
| - feature/login branched off at C, has X,Y,Z,W (4) |
| - main doesn't know about X,Y,Z,W |
| - feature/login doesn't know about D,E,F,G,H,I |
| - They are PARALLEL — until you merge them |
| |
| Use case: build feature/login without breaking main. |
| When login is ready, merge feature/login into main. |
+----------------------------------------------------------+
FIG 5.1 · Branches are parallel timelines
Why Branch? The Three Big Reasons
Branches exist for three reasons. First, isolation: you can build a feature without breaking the stable main branch. If your feature is half-done and a critical bug needs fixing on main, you can switch back, fix it, and switch back to your feature — your half-done work waits patiently. Second, experimentation: want to try a wild rewrite of your auth system? Branch it. If it works, merge. If it doesn't, delete the branch — main is untouched. Third, collaboration: every teammate works on their own branch. Nobody steps on each other's toes. When ready, open a Pull Request to merge.
The Branch Commands
# List all branches (* marks current)
git branch
* main
feature/login
bugfix/navbar
# Create a new branch (but stay on current)
git branch feature/login
# Create AND switch to new branch (most common)
git checkout -b feature/login
Switched to a new branch 'feature/login'
# Modern alternative (Git 2.23+, easier to remember)
git switch -c feature/login
# Switch to an existing branch
git checkout main
git switch main # modern alternative
# Delete a branch (must not be on it)
git branch -d feature/login # safe delete (only if merged)
git branch -D feature/login # force delete (even if unmerged)
# Rename current branch
git branch -m new-name
CHECKOUT vs SWITCH — WHICH TO USE?
Older tutorials use
git checkout for everything (creating branches, switching branches, restoring files). It's overloaded and confusing. In 2019, Git introduced
git switch (for branches) and
git restore (for files) to separate the commands. Both work;
switch is clearer. We'll use
switch in this guide, but you'll see
checkout everywhere online.
Branch Naming Conventions
Branches should have descriptive names. Most teams use a prefix-based convention. The branch name should tell you what is being done and who is doing it (sometimes).
| Prefix | Use Case | Example |
| feature/ | New feature or enhancement | feature/user-auth |
| bugfix/ | Bug fix | bugfix/login-redirect |
| hotfix/ | Urgent production fix | hotfix/security-patch |
| release/ | Release preparation | release/v2.0 |
| docs/ | Documentation changes | docs/api-reference |
| chore/ | Maintenance, deps, configs | chore/update-deps |
| experiment/ | Risky experiments | experiment/new-algo |
WHY THIS MATTERS IN INDUSTRY
No real software team works directly on
main. Ever. Every feature, every fix, every experiment happens on a branch. When you join a company, your first task will be: "create a branch, make your change, open a PR". If you can't branch confidently, you can't contribute. Master branching, and you unlock the door to real-world development.
THE PARALLEL UNIVERSE
Captain Commit has detected a paradox: Gian is editing main directly and breaking the build for everyone. Your mission: create a parallel universe (a branch), make a change there, and verify that main is untouched.
In your git_and_github_nyc repo, run git switch -c feature/add-todos
Create a new file todos.txt with 3 things you've learned so far
Run git add . then git commit -m "Add learning todos"
Run git switch main to go back to main
Check: ls — todos.txt should NOT be there (main is untouched)
Run git log --oneline --all --graph to see both branches
Run git switch feature/add-todos — todos.txt reappears!
+250 XP · UNLOCKED: Branch Boss badge · You can now work in parallel universes without breaking the timeline
Q1. You're on main and want to start building a new feature called "user profile". Which command creates AND switches to a new branch in one step?
A. git branch feature/user-profile
B. git switch -c feature/user-profile (or git checkout -b feature/user-profile)
C. git new feature/user-profile
D. git create feature/user-profile
Answer: B — git switch -c creates the branch and switches to it in one command. git branch <name> only creates the branch but leaves you on your current branch. The -c flag means "create". (Equivalent older syntax: git checkout -b.)
Q2. You're on feature/login with uncommitted changes, and you try to switch to main. What happens?
A. Git silently moves your changes to main — they get mixed in
B. Git refuses and says "Your local changes would be overwritten" — you must commit or stash first
C. Git deletes your uncommitted changes and switches
D. Git creates a new branch automatically
Answer: B — Git protects you. If your uncommitted changes would conflict with the target branch, Git refuses to switch and tells you to commit or stash first. If the changes don't conflict, Git carries them over to the new branch (which can be confusing). Best practice: always commit or stash before switching branches.
Q3. You finished your feature and merged it into main. The branch feature/login is no longer needed. How do you delete it?
A. git remove feature/login
B. Switch to main first, then git branch -d feature/login
C. Just delete the folder on your computer
D. git delete feature/login
Answer: B — You must switch OFF the branch before deleting it (Git won't let you delete the branch you're standing on). Then git branch -d feature/login safely deletes it (only works if the branch has been merged). Use -D (capital) to force-delete an unmerged branch.
Branches let you build features in isolation. But eventually, that feature is done and needs to come home — back into main. That homecoming is called a merge. Most merges are smooth. Some merges erupt into merge conflicts — the dramatic boss battle of every developer's career. This chapter teaches you both: the smooth merge, and the conflict-resolution dance.
STORY BRIEF
Gian built the login feature on
feature/login. Suneo, meanwhile, built a signup feature on
feature/signup. Both branches modified the same line in
app.py — Gian changed it to handle login, Suneo changed it to handle signup. Gian merged first — clean. Then Suneo tried to merge — Git screamed "MERGE CONFLICT in app.py". Suneo panicked. Captain Commit appeared. "Breathe," he said. "Conflicts are normal. Let me show you how to win this war."
How Merging Works
When you merge branch B into branch A, Git tries to combine the changes automatically. There are two scenarios. Fast-forward merge: branch A hasn't changed since branch B was created. Git just moves A's pointer forward to B's latest commit. Clean, no merge commit needed. Three-way merge: both branches have new commits since they diverged. Git creates a new "merge commit" that has two parents, combining both histories. This is the common case in real projects.
+----------------------------------------------------------+
| FAST-FORWARD vs THREE-WAY MERGE |
+----------------------------------------------------------+
| |
| FAST-FORWARD (main hasn't changed): |
| |
| Before: A---B---C (main) |
| \ |
| X---Y---Z (feature) |
| |
| After: A---B---C---X---Y---Z (main, feature) |
| (main pointer just moves forward to Z) |
| |
| ----------------------------------------------------- |
| |
| THREE-WAY MERGE (both branches changed): |
| |
| Before: A---B---C---D---E (main) |
| \ |
| X---Y---Z (feature) |
| |
| After: A---B---C---D---E (main) |
| \ \ |
| X---Y---Z--M (main, M=merge commit) |
| |
| M is a new commit with TWO parents: E and Z |
+----------------------------------------------------------+
FIG 6.1 · The two merge dances
The Merge Command
# Step 1: Switch to the branch you want to merge INTO
git switch main
# Step 2: Merge the feature branch INTO current branch (main)
git merge feature/login
Updating c9c570f..a3b4c5d
Fast-forward
app.py | 5 +++--
1 file changed, 4 insertions(+), 1 deletion(-)
# Step 3: Delete the merged branch (optional, good practice)
git branch -d feature/login
# Note: if both branches changed, you'll get a 3-way merge:
Merge made by the 'ort' strategy.
app.py | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
Merge Conflicts — The Boss Battle
A merge conflict happens when both branches changed the same lines of the same file, and Git can't decide which version to keep. Git stops the merge, marks the conflicting lines in the file with scary-looking markers, and asks you to choose. This is not a bug. This is Git respecting your judgment. Let's see what a conflict looks like.
# After running `git merge feature/signup`, you see:
Auto-merging app.py
CONFLICT (content): Merge conflict in app.py
Automatic merge failed; fix conflicts and then commit the result.
# Open app.py in VS Code. You'll see this:
<<<<<<< HEAD
def login():
return "Login page"
=======
def signup():
return "Signup page"
>>>>>>> feature/signup
# Translation:
# <<<<<<< HEAD = current branch (main) version
# ======= = separator between the two versions
# >>>>>>> feature/signup = incoming branch version
Resolving a Conflict — Step by Step
Resolving a conflict means choosing how the final code should look. You can keep main's version, keep the feature branch's version, combine both, or rewrite entirely. VS Code has a beautiful built-in conflict resolver with buttons like "Accept Current", "Accept Incoming", "Accept Both". But you should also know how to do it manually.
# Step 1: Open the conflicted file in VS Code
code app.py
# Step 2: Edit the file to remove the conflict markers
# Choose ONE of these (or write your own combination):
# Option A: Keep BOTH functions (manually combined):
def login():
return "Login page"
def signup():
return "Signup page"
# Option B: Keep only main's version (delete the rest + markers):
def login():
return "Login page"
# Option C: Keep only feature's version:
def signup():
return "Signup page"
# Step 3: Save the file
# Step 4: Stage the resolved file
git add app.py
# Step 5: Commit the merge (Git auto-fills the message)
git commit -m "Merge feature/signup into main"
# Step 6: Verify the merge is complete
git status
On branch main
nothing to commit, working tree clean
# If you want to ABORT the merge and start over:
git merge --abort
CONFLICT RESOLUTION GOLDEN RULES
Never commit a file with conflict markers still in it. Always remove the
<<<<<<<,
=======, and
>>>>>>> lines.
Always test your code after resolving — the merge might compile but break logic.
When in doubt, abort:
git merge --abort cancels the merge and puts you back where you started. Better to abort than to commit broken code.
WHY THIS MATTERS IN INDUSTRY
Merge conflicts are the #1 source of team friction in software development. Junior devs panic. Senior devs breathe, read the conflict, talk to the teammate if needed, and resolve calmly. The ability to resolve conflicts cleanly — without losing anyone's work, without breaking the build — is a top-3 most-valued skill in team development. Practice it. Embrace it. You will face hundreds of conflicts in your career.
THE CONFLICT RESOLVER
Captain Commit has set up a training battle. Two branches have modified the same file. Your mission: trigger the conflict, see the markers with your own eyes, resolve it manually, and complete the merge. Victory awaits.
On main, edit disaster_report.txt — add a line "END OF REPORT" at the bottom
Commit: git add . && git commit -m "Add end marker to report"
Create & switch to branch: git switch -c experiment/add-intro
On this branch, edit the SAME file — add "START OF REPORT" at the top, but ALSO add a different line at the bottom (e.g. "REPORT CONCLUDES HERE")
Commit: git add . && git commit -m "Add intro and outro to report"
Switch to main: git switch main
Merge: git merge experiment/add-intro — CONFLICT!
Open the file, see the markers, resolve by keeping both intro and outro lines
Stage & commit: git add . && git commit -m "Merge experiment/add-intro"
+300 XP · UNLOCKED: Merge Master badge · You faced the boss battle and won · Conflicts no longer scare you
Q1. You're on main and run git merge feature/x. You get "CONFLICT (content): Merge conflict in app.py". What should your FIRST action be?
A. Delete the feature branch and pretend nothing happened
B. Open the conflicted file and look at the <<<<<<< ======= >>>>>>> markers to understand the conflict
C. Run git push immediately
D. Reinstall Git
Answer: B — Conflicts are normal. Open the file, find the conflict markers, understand what each side wants, then decide how to combine them. If you're overwhelmed, git merge --abort cancels and returns you to pre-merge state. Never commit a file with markers still in it.
Q2. After resolving a conflict in app.py by editing the file, what's the correct sequence to finish the merge?
A. git push then git commit
B. git add app.py then git commit -m "Merge..."
C. git commit then git add app.py
D. Just save the file — Git auto-commits
Answer: B — You must stage the resolved file with git add (telling Git "I resolved this"), then commit to complete the merge. Git often pre-fills a default merge commit message; you can keep it or customize it. Order matters: add before commit.
Q3. When does Git perform a "fast-forward" merge instead of a three-way merge?
A. When the feature branch has only one commit
B. When the target branch (e.g. main) has not changed since the feature branch was created
C. When both branches changed the same files
D. When you use the --ff flag
Answer: B — If main hasn't moved forward since the feature branch split off, Git can just move main's pointer forward to the feature branch's latest commit. No merge commit is needed. If main has new commits, Git must do a three-way merge and create a merge commit. You can force no-ff with --no-ff to always create a merge commit (useful for tracking feature history).
Everything so far has been local — Git on your laptop, commits living in your .git folder, branches dancing in your machine. Now we go online. In this chapter, you create a GitHub account, host your repo in the cloud, and learn the sacred commands that connect local Git to remote GitHub. This is where the magic of collaboration begins.
STORY BRIEF
Gian finished the weather app on his laptop. 47 commits. 8 branches. A beautiful Git history. Then his laptop fell. Hard drive died. Everything was lost — except, nothing was lost. Because two hours earlier, Gian had pushed his repo to GitHub. Captain Commit smiles: "This is why we go remote. Your code lives in two places now — your laptop and the cloud. Neither has to die for the other to survive."
Step 1: Create Your GitHub Account
Go to github.com and sign up with the same email you used in git config. Choose a professional username — this is your public identity as a developer. coolhacker2007 is not a good username. priya-sharma or rahuldev is. Your GitHub profile will be visible to recruiters, so treat it like a resume.
Step 2: Create Your First Repository on GitHub
# On GitHub.com:
# 1. Click the "+" icon in top-right corner
# 2. Select "New repository"
# 3. Name it: git-and-github-nyc
# 4. Description: "My first Git & GitHub project"
# 5. Choose Public (so recruiters can see your work)
# 6. DO NOT check "Add README" (you already have local files)
# 7. Click "Create repository"
# GitHub will show you the URL of your new repo:
https://github.com/yourname/git-and-github-nyc.git
Step 3: Connect Local Repo to GitHub
Your local repo exists. Your GitHub repo exists. They don't know about each other yet. We use git remote add to introduce them. The convention is to call the remote "origin" — short for "the origin of this repo's remote copy".
# In your local repo folder:
git remote add origin https://github.com/yourname/git-and-github-nyc.git
# Verify the remote was added:
git remote -v
origin https://github.com/yourname/git-and-github-nyc.git (fetch)
origin https://github.com/yourname/git-and-github-nyc.git (push)
# If you made a typo, remove the remote and re-add:
git remote remove origin
git remote add origin <correct-url>
Step 4: Push Your Code to GitHub
Now we send all your local commits to GitHub. The command is git push. The first time, you use -u (short for --set-upstream) to remember the connection — after that, you just type git push and Git knows where to go.
# First-time push: link local main to remote origin/main
git push -u origin main
Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Writing objects: 100% (12/12), 1.34 KiB | 1.34 MiB/s, done.
Total 12 (delta 0), reused 0 (delta 0)
To https://github.com/yourname/git-and-github-nyc.git
* [new branch] main -> main
# Subsequent pushes (just two words):
git push
# GitHub may ask for username & password (use Personal Access Token)
# OR set up SSH keys to skip authentication (see tip below)
PASSWORD AUTHENTICATION IS DEAD
GitHub no longer accepts your account password for
git push over HTTPS. You must use either a
Personal Access Token (PAT) or
SSH keys. For beginners: go to GitHub → Settings → Developer settings → Personal access tokens → Generate new token. Copy the token (you'll only see it once!) and use it as your password when Git asks. For long-term setup, SSH keys are better — search "GitHub SSH setup" for a 5-minute tutorial.
Step 5: Pull — Get Changes from GitHub
When someone else (or you, on another laptop) pushes changes to GitHub, those changes don't automatically appear on your laptop. You must git pull to fetch and merge them. Always pull before you push, especially when working in a team.
# Get latest changes from GitHub and merge into your local main
git pull origin main
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 698 bytes | 174.00 KiB/s, done.
From github.com:yourname/git-and-github-nyc
* branch main -> FETCH_HEAD
c9c570f..a3b4c5d main -> origin/main
Updating c9c570f..a3b4c5d
Fast-forward
app.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
# If you just want to SEE what's new without merging yet:
git fetch origin
git log origin/main --oneline # see commits without applying them
Step 6: Clone — Copy a Repo from GitHub
When you want to work on someone else's GitHub repo (or your own repo on a new laptop), you clone it. Cloning downloads the entire repo — every file, every commit, every branch — to your laptop and sets up the remote connection automatically.
# Clone a repo (creates a new folder with the repo name)
git clone https://github.com/yourname/git-and-github-nyc.git
Cloning into 'git-and-github-nyc'...
remote: Enumerating objects: 15, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 15 (delta 2), reused 12 (delta 1), pack-reused 0
Receiving objects: 100% (15/15), 4.21 KiB | 4.21 MiB/s, done.
Resolving deltas: 100% (2/2), done.
# cd into the cloned folder
cd git-and-github-nyc
# Verify remote is set up automatically:
git remote -v
origin https://github.com/yourname/git-and-github-nyc.git (fetch)
origin https://github.com/yourname/git-and-github-nyc.git (push)
+----------------------------------------------------------+
| LOCAL <--> REMOTE COMMAND MAP |
+----------------------------------------------------------+
| |
| YOUR LAPTOP GITHUB |
| (local repo) (remote repo) |
| |
| +-----------+ git push -u origin main +---------+ |
| | local | --------------------------> | remote | |
| | commits | | repos | |
| | | <-------------------------- | | |
| +-----------+ git pull origin main +---------+ |
| |
| +-----------+ git fetch (download only) |
| | local | <-------------------------- |
| | | git clone (first download) |
| +-----------+ |
| |
| COMMANDS CHEAT: |
| - push: send local commits to remote |
| - pull: fetch + merge remote commits into local |
| - fetch: download remote commits (no merge) |
| - clone: full download of a remote repo |
+----------------------------------------------------------+
FIG 7.1 · The local-remote dance
WHY THIS MATTERS IN INDUSTRY
At any job, your workflow is: clone the team repo → create a branch → commit → push → open PR → review → merge. Every single day. If
push,
pull, and
clone feel natural, you can join any team on day one. If they feel scary, you'll freeze. Practice this chapter until these commands are muscle memory. Bonus: GitHub is also your portfolio. A profile with 10 well-maintained repos is more impressive than a 4.0 GPA with no GitHub.
THE FIRST PUSH
Captain Commit has prepared your initiation rite. Your local repo is ready. GitHub is waiting. Your mission: create a GitHub repo, connect it, push your code, and watch your work appear in the cloud for the first time. This is the moment you become a real developer.
Go to github.com, sign in, click "+" → "New repository"
Name it git-and-github-nyc, set to Public, NO README, click Create
Copy the repo URL from GitHub
In your local repo: git remote add origin <URL>
Verify: git remote -v should show origin pointing to your URL
Push: git push -u origin main
If asked for credentials, use a Personal Access Token (GitHub settings)
Refresh your GitHub repo page — your files should be visible!
Bonus: make a small edit locally, git add . && git commit -m "Test push" && git push
+350 XP · UNLOCKED: Remote Ranger badge (halfway) · Your code now lives in the cloud · Recruiters can finally see your work
Q1. You ran git push but got "Permission denied (publickey)" or "Authentication failed". What's the most likely cause?
A. Your internet is broken
B. GitHub no longer accepts account passwords — you need a Personal Access Token or SSH key
C. You typed the URL wrong
D. Your repo is too big
Answer: B — Since 2021, GitHub requires either a Personal Access Token (PAT) or SSH key for Git operations over HTTPS. Your account password won't work. Generate a PAT in GitHub → Settings → Developer settings → Personal access tokens. Use it as your password when Git asks. For long-term setup, SSH keys are better (set up once, never type credentials again).
Q2. What's the difference between git pull and git fetch?
A. They're identical — both download and merge
B. fetch only downloads remote changes; pull downloads AND merges them into your current branch
C. pull is for branches, fetch is for files
D. fetch deletes local changes; pull doesn't
Answer: B — git fetch downloads remote commits into a hidden "remote-tracking" branch (like origin/main) but doesn't touch your working files. git pull = git fetch + git merge. Use fetch when you want to see what's new without committing to merging. Use pull when you're ready to update your local branch.
Q3. You want to start working on an open-source project hosted on GitHub. What's the FIRST command you run after finding the repo?
A. git push
B. git clone <repo-url>
C. git init
D. git commit
Answer: B — git clone downloads the entire repo to your laptop, including all history and branches, and sets up the origin remote automatically. You don't init a new repo (the repo already exists on GitHub). You don't push (you have nothing to push yet — you just got the code). Clone first, then branch, then commit, then push.
A Pull Request (PR) is the heartbeat of team collaboration on GitHub. It's a formal "please review and merge my changes" request. PRs are where code review happens, where teammates discuss, where bugs are caught before they hit production, and where junior devs learn from senior devs. Every real software team uses PRs. Master this chapter, and you can contribute to any codebase on Earth — including open-source projects with millions of users.
STORY BRIEF
Suneo finished building the signup feature on his branch
feature/signup. He pushed it to GitHub. But he didn't merge it directly into main. Instead, he opened a Pull Request — a webpage on GitHub where Gian and Nobita could review his code, leave comments, suggest changes, and approve. After two rounds of review, Suneo's PR was merged. "This," said Captain Commit, "is how grown-up software gets built. Nobody merges their own code. The team owns the code."
The PR Workflow — Step by Step
The standard PR workflow has 7 steps. Memorize them. They are the rhythm of professional development.
+----------------------------------------------------------+
| THE PULL REQUEST LIFECYCLE |
+----------------------------------------------------------+
| |
| 1. FORK your copy of someone else's repo |
| | |
| 2. CLONE download your fork to your laptop |
| | |
| 3. BRANCH create a feature branch |
| | |
| 4. COMMIT make changes, commit with clear messages |
| | |
| 5. PUSH push your branch to your fork on GitHub |
| | |
| 6. PR open a Pull Request on GitHub |
| | (target: the original repo's main branch) |
| | |
| 7. REVIEW teammates review, comment, request changes |
| | you push more commits to same branch |
| | they auto-appear in the PR |
| | |
| 8. MERGE after approval, merge the PR into main |
| delete the branch. Celebrate. |
+----------------------------------------------------------+
FIG 8.1 · The sacred PR lifecycle
Forking vs Cloning — The Critical Difference
Many beginners confuse fork and clone. Here's the difference. Clone downloads a repo to your laptop. You can clone any repo you have read access to. But you can only push to repos you own or have write access to. Fork makes a personal copy of someone else's repo under your own GitHub account. You can then clone your fork, make changes, push to your fork, and open a PR against the original repo. Forking is for contributing to projects you don't own. Cloning is for getting any repo onto your laptop.
| Action | What it does | When to use |
| Fork | Creates a personal copy of someone else's repo under YOUR GitHub account | You want to contribute to a project you don't own (open source) |
| Clone | Downloads any repo to your laptop (you need read access) | You want to work on a repo locally (yours or forked) |
| Branch | Creates a parallel line of development inside a repo | Starting any new feature or fix |
| Push | Sends local commits to a remote (your fork or original repo) | After committing — to share your work |
| Pull Request | Asks the repo owner to merge your branch into their repo | When your feature is ready for review/merge |
Opening Your First Pull Request
After pushing your branch to GitHub, opening a PR is just a few clicks. GitHub's UI is genuinely friendly here. Go to your repo page on GitHub, and you'll see a yellow banner: "Compare & pull request" — click it. Write a clear title and description, click "Create pull request", and your PR is live.
# Step 1: Create & switch to a new branch
git switch -c feature/add-readme
# Step 2: Make your changes (edit files)
echo "# My Project" > README.md
# Step 3: Stage & commit
git add README.md
git commit -m "Add project README"
# Step 4: Push the branch to GitHub
git push -u origin feature/add-readme
# Step 5: Go to GitHub.com → your repo
# Click "Compare & pull request" yellow button
# Write PR title: "Add project README"
# Write PR description:
# ## What does this PR do?
# Adds a README.md with project title and description.
#
# ## Why is this needed?
# Every repo needs a README so visitors understand the project.
#
# ## How to test?
# Just view the README.md file on GitHub.
# Step 6: Click "Create pull request"
# Step 7: Wait for review. If changes requested:
echo "## Description" >> README.md
git add README.md
git commit -m "Add description section to README"
git push # auto-updates the PR!
# Step 8: After approval, click "Merge pull request" on GitHub
Writing a Great PR Description
A good PR description has three parts: What does this PR do? Why is it needed? How can the reviewer test it? A bad PR description is just "fix" or "added stuff". A great PR description makes the reviewer's job easy and shows you respect their time.
PR GOLDEN RULES
One PR = one logical change. Don't mix a new feature with a refactor and a bug fix in the same PR.
Keep PRs small — under 400 lines of diff if possible. Reviewers can't review 2000-line PRs effectively.
Write a clear description — what, why, how to test.
Respond to feedback gracefully — don't take review comments personally. They're about the code, not you.
Don't merge your own PR unless you have to. The whole point is peer review.
WHY THIS MATTERS IN INDUSTRY
Pull Requests are how the world's software gets built. Linux kernel, React, TensorFlow, your college's coding club project — all use PRs. Open-source contribution means opening PRs to repos you don't own. A GitHub profile with 10 merged PRs to popular open-source repos is more impressive to recruiters than a 4.0 GPA with no public code. PRs are how the world sees your work. Make them count.
THE PR PIONEER
Captain Commit has taught you the sacred PR ritual. Now it's your turn to perform it. Your mission: create a branch, make a meaningful change, push it, open a Pull Request on GitHub, and (if you have a friend) ask them to review it. If you're solo, review and merge your own PR (just this once).
In your local repo: git switch -c feature/add-readme
Create a README.md file with a project title and description
git add README.md && git commit -m "Add project README"
git push -u origin feature/add-readme
Go to your repo on GitHub.com
Click the yellow "Compare & pull request" button
Write a clear PR title and description (what/why/how-to-test)
Click "Create pull request"
Click "Merge pull request" → "Confirm merge"
Back on laptop: git switch main && git pull origin main to sync
+200 XP · UNLOCKED: Remote Ranger badge (complete) · You can now contribute to ANY codebase on Earth · The open-source world is yours
Q1. You want to contribute to React (Facebook's open-source library). You don't have write access to facebook/react. What's the first step?
A. Email Facebook and ask for access
B. Fork the facebook/react repo to your own GitHub account, then clone your fork
C. Clone facebook/react directly — you'll figure out pushing later
D. You can't contribute without permission
Answer: B — Forking creates a personal copy of the repo under your GitHub account. You can then clone your fork, make changes, push to your fork, and open a PR against the original facebook/react repo. This is the standard open-source contribution workflow.
Q2. You opened a PR. The reviewer requested changes. What do you do?
A. Close the PR and open a new one
B. Make the requested changes locally, commit, and push to the SAME branch — the PR auto-updates
C. Delete the PR and start over
D. Argue with the reviewer in comments until they give up
Answer: B — PRs are tied to branches. When you push new commits to the same branch, they automatically appear in the PR. No need to close and reopen. Just git add → commit → push as usual. The reviewer will see your new commits and can re-review.
Q3. Which PR description is best?
A. "fix"
B. "Added some stuff, please merge"
C. "What: Add email validation to registration form. Why: Prevents users from signing up with invalid emails. How to test: Try registering with 'test' (should fail) and 'test@example.com' (should succeed)."
D. "asdfasdfasdf"
Answer: C — A great PR description answers three questions: What does this PR do? Why is it needed? How can the reviewer test it? This makes review fast and shows you respect the reviewer's time. Bad PR descriptions ("fix", "stuff") make reviewers guess and slow everyone down. Bad PRs get rejected. Good PRs get merged.
This is the chapter you'll return to most. Every developer — junior, senior, principal — makes mistakes. You commit the wrong file. You push a bug. You accidentally delete a branch. You run git reset --hard and watch three hours of work vanish. This chapter is your emergency toolkit. Bookmark it. Tattoo it on your arm. When things go wrong, come back here.
STORY BRIEF
Gian ran
git reset --hard HEAD~3 thinking he was undoing one commit. He actually nuked three commits — including the one with his completed login feature. He stared at his terminal in horror. "Don't panic," said Captain Commit, materializing from thin air. "Git never forgets. Let me show you
git reflog — the time machine within the time machine."
The Four Levels of Undo
Git gives you four different "undo" tools, each for a different situation. Knowing which one to use is the mark of a confident developer. Use the wrong one, and you make things worse. Use the right one, and you're a hero.
| Tool | What it undoes | Safety level |
| git checkout -- <file> | Discards uncommitted changes in a file | Dangerous — changes are gone forever, no recovery |
| git reset HEAD <file> | Unstages a staged file (keeps your changes) | Safe — your work is still in working directory |
| git revert <commit> | Creates a NEW commit that undoes a previous commit | Safe & public — preserves history, safe for shared branches |
| git reset --<mode> <commit> | Moves HEAD back to an older commit | Depends on mode: --soft safe, --mixed safe, --hard DANGEROUS |
| git reflog | Shows every HEAD movement — even after reset | Read-only — your safety net for any disaster |
Level 1: Discard Uncommitted Changes
You edited a file, hate the changes, and want to go back to the last committed version. Use git restore (modern) or git checkout -- (classic). This nukes your uncommitted work — there's no recovery.
# Discard changes in ONE file (modern syntax)
git restore app.py
# Same thing, classic syntax (older tutorials)
git checkout -- app.py
# Discard changes in ALL files (NUCLEAR)
git restore .
# Unstage a staged file (keep the changes)
git restore --staged app.py
# Old syntax: git reset HEAD app.py
# WARNING: discarded changes are GONE FOREVER
# Only do this if you're sure!
Level 2: Undo a Commit (Safely)
You committed something you shouldn't have, and you already pushed it. Do not use git reset on shared branches. Instead, use git revert, which creates a NEW commit that undoes the target commit. This preserves history and is safe for shared branches like main.
# Find the commit hash you want to undo
git log --oneline
a3b4c5d (HEAD) Bad commit - introduced a bug
c9c570f Good commit - login feature
b8a7c6d Initial commit
# Revert the bad commit (creates a new "undo" commit)
git revert a3b4c5d
[main d4e5f6g] Revert "Bad commit - introduced a bug"
1 file changed, 1 deletion(+)
# History now shows: Bad commit + Revert commit
git log --oneline
d4e5f6g (HEAD) Revert "Bad commit - introduced a bug"
a3b4c5d Bad commit - introduced a bug
c9c570f Good commit - login feature
b8a7c6d Initial commit
# Safe to push — history is preserved, teammates can see what happened
git push
Level 3: Reset to a Previous Commit (Local Only)
git reset moves your branch pointer back to an older commit, effectively "erasing" the commits after it. There are three modes. Use this only on local branches you haven't pushed yet. Using git reset on a shared branch will cause chaos for your teammates.
# Three modes of reset:
# --soft: moves HEAD back, keeps changes STAGED
git reset --soft HEAD~1
# Commit is gone, but your changes are in staging area
# --mixed (default): moves HEAD back, keeps changes UNSTAGED
git reset HEAD~1
git reset --mixed HEAD~1 # same thing, explicit
# Commit is gone, changes are in working directory (unstaged)
# --hard: moves HEAD back, DELETES ALL CHANGES
git reset --hard HEAD~1
# Commit is gone AND all changes are GONE FOREVER
# USE WITH CAUTION — this is the nuclear option
# Reset to a specific commit by hash:
git reset --hard c9c570f
# HEAD~1 means "one commit before HEAD"
# HEAD~3 means "three commits before HEAD"
NEVER RESET A SHARED BRANCH
If you've already pushed commits to GitHub,
do not use git reset to remove them. Other teammates may have pulled those commits. Use
git revert instead — it adds a new commit that undoes the bad one, preserving history. Reset is for local cleanup only. The only exception: you can force-push a reset branch (
git push --force), but only if you're 100% sure no one else has pulled. Even then, prefer
--force-with-lease for safety.
Level 4: The Reflog — Your Final Safety Net
Even after a git reset --hard, your commits are not truly gone. Git keeps a record of every HEAD movement in the reflog. The reflog is your time machine within the time machine. If you accidentally reset away commits, git reflog shows you where they were, and you can recover them.
# View the reflog (history of HEAD movements)
git reflog
d4e5f6g HEAD@{0}: reset: moving to HEAD~1
a3b4c5d HEAD@{1}: commit: Bad commit - introduced a bug
c9c570f HEAD@{2}: commit: Good commit - login feature
b8a7c6d HEAD@{3}: commit (initial): Initial commit
# Oh no! I just did `git reset --hard HEAD~1` and lost commit a3b4c5d
# But it's still in the reflog!
# Recover it by resetting to that reflog entry:
git reset --hard a3b4c5d
# Or use the HEAD@{} syntax:
git reset --hard HEAD@{1}
# Verify recovery
git log --oneline
a3b4c5d (HEAD) Bad commit - introduced a bug
c9c570f Good commit - login feature
b8a7c6d Initial commit
# PHEW. Disaster averted.
# Reflog keeps entries for ~90 days by default.
+----------------------------------------------------------+
| GIT UNDO DECISION TREE |
+----------------------------------------------------------+
| |
| Did you commit yet? |
| | |
| +-- NO --> git restore <file> (discard changes) |
| | |
| +-- YES --> Did you push to GitHub? |
| | |
| +-- NO --> git reset --soft HEAD~1 |
| | (undo commit, keep changes) |
| | |
| +-- YES --> git revert <commit> |
| (add undo commit, push safely) |
| |
| Lost commits after `git reset --hard`? |
| | |
| +-- git reflog (find lost commit) |
| +-- git reset --hard <hash-from-reflog> (recover) |
+----------------------------------------------------------+
FIG 9.1 · The undo decision tree
WHY THIS MATTERS IN INDUSTRY
Every senior developer has run
git reset --hard by accident and lost work. The difference between a junior and a senior is: the senior knows about
git reflog and recovers in 30 seconds. The junior cries and rewrites everything. This chapter is the difference between panic and poise. Print it. Hang it on your wall.
THE TIME TRAVELER
Captain Commit has staged a controlled disaster. You will create commits, undo them with revert, undo them with reset, lose work, and recover it with reflog. By the end, you will fear no Git disaster.
Create 3 commits on main (e.g. add lines to a file)
Run git log --oneline — note the 3 commit hashes
Use git revert to undo the middle commit (safe undo)
Run git log --oneline — see the revert commit added
Now create 2 more commits, then git reset --hard HEAD~2
Run git log --oneline — those 2 commits are gone!
Run git reflog — find the lost commit hash
Run git reset --hard <lost-hash> — RECOVER them!
Run git log --oneline — celebrate, your commits are back
+300 XP · UNLOCKED: Time Traveler skill · You can now undo ANY Git disaster · Captain Commit bows to you
Q1. You pushed a bad commit to main on GitHub. Your teammates have already pulled it. What's the SAFE way to undo it?
A. git reset --hard HEAD~1 then git push --force
B. git revert <bad-commit-hash> then git push
C. Delete the repo and start over
D. Email everyone to ignore that commit
Answer: B — git revert creates a NEW commit that undoes the bad one. This preserves history (the bad commit + the revert are both visible) and is safe for shared branches. Force-pushing a reset destroys history your teammates may have based work on — never do this on main or any shared branch.
Q2. You ran git reset --hard HEAD~3 and lost 3 commits you actually wanted. Are they gone forever?
A. Yes, --hard permanently deletes commits
B. No — run git reflog to find the lost commit hashes, then git reset --hard <hash> to recover them
C. No — they're in your recycle bin
D. Yes, unless you have a backup on GitHub
Answer: B — git reflog is your safety net. It records every HEAD movement, including resets. Lost commits stay recoverable for ~90 days. Find the hash in reflog, then git reset --hard <hash> to bring them back. This is one of the most valuable Git skills you can learn.
Q3. What's the difference between git reset --soft and git reset --hard?
A. --soft is for small files, --hard is for big files
B. --soft keeps your changes in the staging area; --hard deletes all changes from your working directory
C. --soft is online, --hard is offline
D. They're the same thing with different names
Answer: B — --soft moves HEAD back but keeps your changes staged (ready to re-commit). --mixed (default) moves HEAD back and keeps changes unstaged. --hard moves HEAD back AND deletes all changes — use only when you're certain. Most "undo a commit but keep my work" scenarios want --soft.
You've made it. You know the fundamentals. Now let's add four advanced power-ups to your arsenal: .gitignore (tell Git what to ignore), git stash (save work without committing), git cherry-pick (move a single commit), and git rebase (rewrite history like a pro). These are the tools that separate casual Git users from true Git Gods.
Power-Up 1: .gitignore — Tell Git What to Ignore
Not every file belongs in version control. node_modules/, .env, build artifacts, OS files like .DS_Store, editor configs — these should never be committed. The .gitignore file tells Git which files and folders to skip. Create a .gitignore in your repo root, list patterns to ignore, and Git will skip them forever.
# Create a .gitignore file in your repo root
touch .gitignore
# Common .gitignore contents:
# Dependencies
node_modules/
vendor/
__pycache__/
*.pyc
# Environment & secrets (NEVER commit these!)
.env
.env.local
*.pem
*.key
# Build artifacts
dist/
build/
*.exe
*.dll
*.so
# OS files
.DS_Store
Thumbs.db
desktop.ini
# Editor files
.vscode/
.idea/
*.swp
*.swo
# Logs
*.log
logs/
# Commit the .gitignore itself!
git add .gitignore
git commit -m "Add .gitignore"
NEVER COMMIT .env FILES
Files containing secrets (API keys, database passwords, tokens) must NEVER be committed. A single committed
.env file can leak your AWS keys to the world and cost you thousands of dollars in crypto-mining attacks. Always add
.env to
.gitignore BEFORE you create the file. If you already committed a secret, assume it's compromised — rotate the key immediately, even if you remove the file in a later commit (it's still in history).
Power-Up 2: git stash — Save Without Committing
You're halfway through a feature when an urgent bug needs fixing on main. You don't want to commit half-done work, but you can't switch branches with uncommitted changes either. git stash saves your changes temporarily, cleans your working directory, and lets you switch. When you come back, git stash pop restores your work.
# Save current changes (uncommitted) to stash
git stash
# Working directory is now CLEAN (matches last commit)
git status
nothing to commit, working tree clean
# Switch to main, fix the urgent bug, commit, push
git switch main
git switch -c hotfix/urgent-bug
# ... fix bug, commit, push ...
# Come back to your feature branch
git switch feature/my-feature
# Restore your stashed changes
git stash pop
# List all stashes (you can have multiple)
git stash list
stash@{0}: WIP on feature/my-feature: a3b4c5d Add login form
stash@{1}: WIP on main: c9c570f Initial commit
# Apply a specific stash
git stash apply stash@{1}
Power-Up 3: git cherry-pick — Move a Single Commit
Sometimes you make a commit on the wrong branch, and you want to move JUST that commit to another branch — without bringing the rest of the branch's history. git cherry-pick does exactly this. It takes a single commit's changes and applies them as a new commit on your current branch.
# You're on feature/wrong-branch with commit X you want to move
git log --oneline
X (HEAD) Fix critical security bug
Y Add some feature
Z Initial work
# You want X on main, not here. Switch to main:
git switch main
# Cherry-pick commit X (apply it as a new commit on main)
git cherry-pick X
[main a1b2c3d] Fix critical security bug
Date: Mon Jan 15 14:30:00 2026 +0530
1 file changed, 5 insertions(+), 2 deletions(-)
# X's changes are now on main as a new commit
# (The original X is still on feature/wrong-branch)
# If you want to remove X from the original branch:
git switch feature/wrong-branch
git reset --hard HEAD~1 # removes X from this branch
Power-Up 4: git rebase — Rewrite History (Use Carefully)
Rebasing is the most powerful and most dangerous Git command. It rewrites your commit history by replaying your commits on top of another branch. The result is a clean, linear history (no merge commits). But rebase rewrites history — so never rebase commits you've already pushed and shared. The golden rule: rebase local branches, merge shared branches.
+----------------------------------------------------------+
| MERGE vs REBASE |
+----------------------------------------------------------+
| |
| BEFORE: main: A---B---C---D |
| \ |
| feature: X---Y---Z |
| |
| MERGE (preserves history): |
| main: A---B---C---D---M (merge commit) |
| \ / |
| feature: X---Y---Z |
| (M has two parents: D and Z) |
| |
| REBASE (rewrites history): |
| main: A---B---C---D |
| \ |
| feature: X'--Y'--Z' |
| (X,Y,Z are replayed on top of D as X',Y',Z') |
| (Linear history, no merge commit) |
| |
| Use MERGE for shared branches (safe, preserves truth) |
| Use REBASE for local feature branches (clean history) |
+----------------------------------------------------------+
FIG 10.1 · Merge vs rebase — the eternal debate
# You're on feature/my-feature, behind main by 5 commits
git switch feature/my-feature
# Rebase your branch on top of latest main
git fetch origin
git rebase origin/main
# If conflicts occur, resolve them, then:
git add .
git rebase --continue
# To abort the rebase entirely:
git rebase --abort
# Interactive rebase (most powerful):
git rebase -i HEAD~3
# Opens an editor to squash, reorder, edit, or drop commits
# GOLDEN RULE OF REBASE:
# NEVER rebase commits you've already pushed to a shared branch
# Rebase only your local work before sharing it
THE GOLDEN RULE OF REBASE
Never rebase public commits. If a commit exists on a shared branch (main, develop, anything teammates pull from), do NOT rebase it. Rebase rewrites commit hashes — teammates who pull will get conflicts from hell. Only rebase your local feature branches before you push them. Once pushed, treat history as immutable. If you must rewrite pushed history, use
git push --force-with-lease (safer than
--force).
WHY THIS MATTERS IN INDUSTRY
Senior devs use
.gitignore religiously (no junk in repos),
git stash daily (switching contexts fast),
git cherry-pick for hotfixes (move critical fixes between branches), and
git rebase -i to clean up history before opening a PR (squash 10 messy commits into one clean one). These power-ups aren't optional — they're how professionals work fast and keep history beautiful.
THE POWER PLAYER
Captain Commit has one final test before granting you Git God status. Use all four power-ups in a single workflow: ignore files, stash work, cherry-pick a fix, and rebase your branch.
Create a .gitignore file with patterns: *.log, .env, node_modules/
Create a secrets.env file — verify Git ignores it with git status
Make some changes to a file, then git stash them
Verify working dir is clean with git status
Run git stash pop to restore the changes
Create a branch, make a commit, switch to main, cherry-pick that commit
Bonus: try git rebase -i HEAD~3 to see the interactive rebase editor (then quit)
+500 XP · UNLOCKED: Git God badge · You have mastered the advanced arts · The Git world bows to you
Q1. You accidentally committed your .env file containing API keys. What's the FIRST thing you should do?
A. Remove the file in a new commit — done!
B. Rotate/revoke the leaked API keys immediately, then remove the file from history
C. Make the repo private so no one sees it
D. Delete the repo and start over
Answer: B — Assume any committed secret is compromised, even if your repo is private. Bots scan public repos for secrets within minutes. First: rotate/revoke the keys at the source (AWS, GitHub, OpenAI, wherever). Then remove the file from history using git filter-repo or BFG Repo-Cleaner (a simple git rm leaves the secret in old commits). Add .env to .gitignore to prevent future accidents.
Q2. You're on feature/x with uncommitted changes, and you need to fix an urgent bug on main. What's the cleanest workflow?
A. Commit the half-done work, fix the bug, then revert the half-done commit
B. git stash → switch to main → fix bug → commit → switch back → git stash pop
C. Just switch branches — Git will figure it out
D. Delete your changes and start over
Answer: B — git stash is the cleanest solution. It saves your uncommitted work temporarily, cleans the working directory so you can switch branches freely, and git stash pop restores everything when you return. No messy commits, no lost work.
Q3. What's the GOLDEN RULE of git rebase?
A. Always rebase before every commit
B. Never rebase commits that have been pushed to a shared branch — rebase only local work
C. Rebase is the same as merge, use them interchangeably
D. Rebase only on Sundays
Answer: B — Rebase rewrites commit hashes. If teammates have based work on commits you rebase, their history diverges and merge conflicts erupt. Rule: rebase your LOCAL feature branch before pushing. Once pushed, treat history as immutable. If you absolutely must rewrite pushed history, communicate with your team first and use git push --force-with-lease.
Every Git command you'll ever need, organized by category. Print this page. Tape it to your wall. Tattoo it on your forearm. When in doubt, consult the cheat sheet. When not in doubt, consult it anyway.
SETUP
git --versionCheck Git version
git config --global user.name "Name"Set your name
git config --global user.email "email"Set your email
git config --listView all config
STARTING
git initTurn folder into Git repo
git clone <url>Download a remote repo
git fork (GitHub UI)Copy repo to your account
STAGING & COMMITTING
git statusSee what's changed/staged
git add <file>Stage one file
git add .Stage all changes
git commit -m "msg"Commit staged changes
git commit -am "msg"Stage tracked + commit
INSPECTION
git logView commit history
git log --onelineCompact one-line history
git log --graph --allVisual branch tree
git diffSee unstaged changes
git diff --stagedSee staged changes
git show <hash>Show a specific commit
BRANCHING
git branchList branches
git branch <name>Create branch
git switch <name>Switch to branch
git switch -c <name>Create + switch
git checkout -b <name>Older: create + switch
git branch -d <name>Delete merged branch
git branch -D <name>Force-delete branch
git branch -m <new>Rename current branch
MERGING
git merge <branch>Merge branch into current
git merge --abortCancel a conflicted merge
git mergetoolOpen visual merge tool
git cherry-pick <hash>Move one commit to current branch
REMOTE (GITHUB)
git remote add origin <url>Link local to GitHub
git remote -vList remotes
git remote remove <name>Remove a remote
git push -u origin mainFirst push (sets upstream)
git pushPush commits to remote
git push origin <branch>Push a specific branch
git pullFetch + merge from remote
git fetchDownload remote (no merge)
git clone <url>Download full repo
UNDO & RECOVERY
git restore <file>Discard local changes
git restore --staged <file>Unstage a file
git revert <hash>Safe undo (new commit)
git reset --soft HEAD~1Undo commit, keep staged
git reset --mixed HEAD~1Undo commit, keep unstaged
git reset --hard HEAD~1DANGER: undo + delete changes
git reflogView HEAD history (lifesaver)
git stashSave changes temporarily
git stash popRestore stashed changes
git stash listList all stashes
ADVANCED
git rebase <branch>Replay commits on branch
git rebase -i HEAD~NInteractive rebase (squash!)
git rebase --abortCancel a rebase
git tag v1.0Mark a release point
git blame <file>Who wrote each line?
git bisectBinary search for a bug
CONFIG FILES
.gitignoreFiles Git should ignore
.git/configPer-repo config
~/.gitconfigGlobal config (you)
.gitattributesLine endings, binary handling
The 15 most common Git disasters, what they mean, and how to fix them. When Git screams red error text at you, find it here and breathe.
!
fatal: not a git repository
Cause: You ran a Git command outside a Git repo. Fix: cd into your project folder. Run ls -a — if no .git folder, run git init.
!
Please tell me who you are
Cause: You haven't set user.name and user.email. Fix: Run git config --global user.name "Your Name" and git config --global user.email "your@email.com".
!
nothing to commit, working tree clean
Cause: You ran git commit without staging anything first. Fix: Run git add . first, then commit.
!
Permission denied (publickey)
Cause: SSH key not set up for GitHub. Fix: Either use HTTPS with a Personal Access Token, or set up SSH keys (search "GitHub SSH setup").
!
Authentication failed / Bad credentials
Cause: GitHub no longer accepts account passwords over HTTPS. Fix: Generate a Personal Access Token at GitHub → Settings → Developer settings → use it as your password.
!
CONFLICT (content): Merge conflict in <file>
Cause: Both branches changed the same lines. Fix: Open the file, find <<<<<<< ======= >>>>>>> markers, choose which version to keep (or combine), save, git add <file>, git commit. Or git merge --abort to cancel.
!
failed to push some refs (non-fast-forward)
Cause: Remote has commits your local doesn't have. Fix: Run git pull first to fetch and merge remote changes, then git push again.
!
HEAD detached at <hash>
Cause: You checked out a commit hash directly, not a branch. New commits won't be on any branch. Fix: Create a branch first: git switch -c new-branch-name. Or return to main: git switch main.
!
Your local changes would be overwritten by checkout
Cause: You tried to switch branches with uncommitted changes that conflict. Fix: Commit, stash (git stash), or discard (git restore .) your changes first.
!
error: pathspec '<file>' did not match any file(s)
Cause: You typed a filename that doesn't exist. Fix: Check spelling and path. Run ls or git status to see actual filenames.
!
fatal: refusing to merge unrelated histories
Cause: Two repos with no common ancestor. Fix: Usually means you ran git init in a folder, then added a remote with existing history. Use git pull origin main --allow-unrelated-histories to force the merge.
!
error: Your local changes to the following files would be overwritten by merge
Cause: Merge would overwrite your uncommitted work. Fix: Commit or stash your changes first, then re-run the merge.
!
fatal: remote origin already exists
Cause: You tried to add a remote named "origin" but one already exists. Fix: Update the URL: git remote set-url origin <new-url>. Or remove first: git remote remove origin then re-add.
!
warning: LF will be replaced by CRLF
Cause: Windows uses CRLF line endings, Git prefers LF. Just a warning. Fix: Safe to ignore. To silence: git config --global core.autocrlf true (Windows) or false (Mac/Linux).
!
I accidentally ran git reset --hard and lost work!
Cause: You used the nuclear option. Fix: DON'T PANIC. Run git reflog. Find the hash where you were before the reset. Run git reset --hard <hash> to recover. Reflog saves entries for ~90 days.
Tick off each skill as you master it. When every box is checked, you are officially a Git God. Print this page and physically check the boxes with a pen — there's nothing more satisfying.
1
[ ] Git Newbie — 100 XP
[ ] Understand why Git exists · [ ] Explain Git vs GitHub · [ ] Name the 6 problems Git solves
2
[ ] Commit Cadet — 200 XP
[ ] Install Git · [ ] Configure user.name/email · [ ] Run git init · [ ] Make first commit · [ ] Read git log
3
[ ] Branch Boss — 250 XP
[ ] Create a branch · [ ] Switch branches · [ ] Delete a branch · [ ] Use branch naming conventions
4
[ ] Merge Master — 300 XP
[ ] Merge a branch · [ ] Resolve a merge conflict · [ ] Abort a merge · [ ] Explain fast-forward vs 3-way
5
[ ] Remote Ranger — 350 XP
[ ] Push to GitHub · [ ] Pull from GitHub · [ ] Clone a repo · [ ] Open a Pull Request · [ ] Merge a PR
6
[ ] Git God — 500 XP
[ ] Use git revert · [ ] Use git reset (soft/mixed/hard) · [ ] Recover with git reflog · [ ] Configure .gitignore · [ ] Use git stash · [ ] Use git cherry-pick · [ ] Use git rebase (carefully!)
XP TOTAL: 1700 XP NEEDED FOR GIT GOD
Complete all 11 Mystery Missions to earn the full 1700 XP. Each mission rewards XP as you complete it. Don't rush — Git mastery comes from practice, not from speed. Re-read chapters, redo missions, break things on purpose and fix them. That's how you learn.
Every Git and GitHub term you'll encounter, defined in plain English. Bookmark this page — you'll reference it for years.
A-B
BranchA parallel line of development. Branches let you work on features without affecting main.
BisectBinary search through commits to find which one introduced a bug.
BlameShows who last edited each line of a file (and when). Useful for finding bug authors.
C
CheckoutOlder command for switching branches or restoring files. Replaced by switch and restore.
Cherry-pickApply a single commit from one branch onto another.
CloneDownload a full copy of a remote repo to your laptop.
CommitA snapshot of your project at a point in time. Has a unique hash, author, date, message.
ConflictWhen two branches change the same lines and Git can't auto-merge. Requires manual resolution.
D-F
Detached HEADState when HEAD points to a commit, not a branch. New commits won't be on any branch.
DiffShows line-by-line differences between two versions of a file or commit.
Fast-forwardMerge where target branch just moves forward to source branch's commit. No merge commit created.
FetchDownload remote changes without merging them. pull = fetch + merge.
ForkPersonal copy of someone else's GitHub repo. Used for contributing to open source.
H-M
HEADPointer to the commit your working directory is based on. Usually points to current branch.
HEAD~1One commit before HEAD. HEAD~3 = three commits before.
Hash40-char unique ID for each commit (e.g. c9c570f...). Often shortened to 7 chars.
MergeCombine changes from one branch into another. May create a merge commit (3-way) or fast-forward.
ModifiedA tracked file that has been changed since the last commit. Shown as M in git status.
O-R
OriginDefault name for the remote repository. Usually points to your GitHub repo.
PullFetch + merge remote changes into your local branch.
Pull Request (PR)Request to merge your branch into another (usually main) on GitHub. Enables code review.
PushSend your local commits to a remote repository (GitHub).
RebaseReplay your commits on top of another branch. Creates linear history. Don't use on shared branches!
ReflogLog of HEAD movements. Lets you recover "lost" commits after reset --hard.
RemoteA hosted version of your repo (e.g. on GitHub). Named "origin" by convention.
Repository (repo)A folder tracked by Git. Contains your code + .git folder with all history.
ResetMove HEAD/branch pointer to a different commit. Modes: --soft, --mixed, --hard.
RestoreModern command to discard changes or unstage files. Replaces some checkout uses.
RevertCreate a new commit that undoes a previous commit. Safe for shared branches.
S-Z
Staging AreaIntermediate zone between working dir and repo. Where you curate what goes into the next commit.
StashTemporarily save uncommitted changes. git stash pop restores them.
SwitchModern command to change branches. Replaces git checkout <branch>.
TagNamed marker for a specific commit. Used for releases (e.g. v1.0.0).
TrackA file Git is monitoring. Untracked files (??) become tracked after git add.
UntrackedA file in working dir that Git doesn't know about yet. Shown as ?? in git status.
UpstreamThe remote branch your local branch tracks. Set with git push -u.
Working DirectoryThe folder where you edit files. The "live" state, not yet staged or committed.
You've learned the theory. You've done the missions. Now face the Final Boss — a comprehensive challenge that tests every skill you've acquired. Complete this, and you are officially a Git God. No doubts. No imposter syndrome. Earned.
THE SCENARIO
You're a new junior developer at a startup called "WeatherCat". The team has a GitHub repo at
github.com/weathercat/app. Your first task: add a "temperature converter" feature to the app, following the team's PR workflow. Suneo (your teammate) has already pushed a commit that introduces a bug. You must: fix the bug, add your feature, resolve a merge conflict with Suneo, push your branch, open a PR, and (after review) merge it. If you complete every step, you are a Git God.
The 15-Step Final Challenge
# STEP 1: Fork the team repo on GitHub (click Fork button)
# STEP 2: Clone YOUR fork to your laptop
git clone https://github.com/YOURNAME/app.git
cd app
# STEP 3: Add the original team repo as "upstream" remote
git remote add upstream https://github.com/weathercat/app.git
# STEP 4: Create a feature branch
git switch -c feature/temperature-converter
# STEP 5: Create the temperature converter file
echo "def celsius_to_fahrenheit(c): return c * 9/5 + 32" > converter.py
# STEP 6: Stage and commit
git add converter.py
git commit -m "Add celsius-to-fahrenheit converter"
# STEP 7: Push your branch to YOUR fork
git push -u origin feature/temperature-converter
# STEP 8: Open a Pull Request on GitHub
# (target: weathercat/app main, source: your fork's feature branch)
# STEP 9: While waiting for review, fix Suneo's bug
git fetch upstream
git switch main
git merge upstream/main # get latest team code
# STEP 10: Notice Suneo's bug, create a hotfix branch
git switch -c hotfix/suneo-bug
# ... fix the bug in app.py ...
git add app.py
git commit -m "Fix null pointer in get_weather()"
# STEP 11: Cherry-pick the hotfix to main
git switch main
git cherry-pick hotfix/suneo-bug
# STEP 12: Go back to your feature branch and rebase on main
git switch feature/temperature-converter
git rebase main # might trigger conflict!
# STEP 13: If conflict, resolve, add, continue
git add .
git rebase --continue
# STEP 14: Force-push the rebased branch (your branch only!)
git push --force-with-lease origin feature/temperature-converter
# STEP 15: Your PR auto-updates. After approval, click Merge.
# Then sync your local main:
git switch main
git pull upstream main
git push origin main # keep your fork in sync
IF YOU COMPLETED ALL 15 STEPS...
You are officially a Git God. You have demonstrated: forking, cloning, branching, committing, pushing, PR creation, fetching, merging, hotfix branches, cherry-picking, rebasing, conflict resolution, force-push safety, and post-merge sync. These are the exact skills senior engineers use every day. Print this page, sign it, frame it. You earned it.
CERTIFICATE OF MASTERY
This certifies that
_______________________________
has completed all 11 Mystery Missions and the Final Boss Challenge,
mastering Git and GitHub from Newbie to Git God.
SIGNED: CAPTAIN COMMIT