Git & GitHub: From Zero to Collaborating Like a Pro
A tutorial for humans, by a human. No fluff. Real examples. The stuff nobody explains properly.
Table of Contents
- Before We Start — Why Does Git Even Exist?
- Part 1: What Problem Does Git Actually Solve?
- Part 2: Installing Git and Basic Setup
- Part 3: Your First Repository
- Part 4: The Three Stages of Git (This is the Key Concept)
- Part 5: Branches — The Heart of Git
- Part 6: Merging — Bringing Work Back Together
- Part 7: Rebase — The Cleaner Alternative
- Part 8: GitHub — Putting It Online
- Part 9: Clone — Getting Someone Else's Code
- Part 10: Pull Requests — How Real Teams Work
- Part 11: Multiple People Working Together
- Part 12: The Commands You'll Use Every Day
- Part 13: Undoing Mistakes
- Part 14: Real Example — A Full Collaborative Session
- Part 15: .gitignore — What NOT to Track
- Quick Reference Cheatsheet
- Where to Go From Here

Before We Start — Why Does Git Even Exist?
Let's go back to 2005.
Linus Torvalds — the Finnish-American guy who created the Linux kernel — had a problem. He was managing one of the biggest open-source projects in the world, with thousands of contributors sending him code from every corner of the planet. And he was doing it with a proprietary tool called BitKeeper.
Then BitKeeper revoked the free license. Just like that.
Linus, being Linus, didn't complain. He sat down and in 10 days wrote his own version control system from scratch. He called it Git — which is British slang for "an unpleasant person." He later said he named it after himself.
"I'm an egotistical bastard, and I name all my projects after myself. First Linux, now Git." — Linus Torvalds
Git was designed with one goal: handle the Linux kernel's development — massive scale, distributed contributors, speed. Everything else in version control at the time was slow, centralized, and painful. Git was the opposite.
Fast forward to 2008. A couple of developers built a website on top of Git that let you host your code, collaborate with others, and contribute to projects without knowing anyone personally. They called it GitHub.
Microsoft bought GitHub in 2018 for $7.5 billion. But Git itself? Still open source. Still maintained by the community. Still the same tool Linus built in 10 days.
That's the story. Now let's actually learn it.
Part 1: What Problem Does Git Actually Solve?
Imagine you're writing a school essay. You save it as:
essay.docx essay_final.docx essay_final_v2.docx essay_ACTUALLY_final.docx essay_ACTUALLY_final_submitted.docx
We've all been there. Now imagine doing that with a team of 5 people, all editing the same file at the same time. It's chaos.
Git solves this. It's a version control system — it tracks every change you make, who made it, when, and why. You can travel back in time, work in parallel without stepping on each other's toes, and merge changes together intelligently.
GitHub is just a website that hosts your Git repositories in the cloud so others can see and contribute to them.
Think of it this way:
- Git = the tool on your computer
- GitHub = Google Drive, but for code, with superpowers
Part 2: Installing Git and Basic Setup
Install Git
- Mac: Open terminal, type
git --version. If it's not there, it'll prompt you to install it. Or use brew:brew install git - Windows: Download from git-scm.com
- Linux:
sudo apt install git(Ubuntu/Debian) orsudo dnf install git(Fedora)
Tell Git Who You Are
Git needs to know your name and email so it can label your changes. Run these once:
git config --global user.name "Sarah Johnson" git config --global user.email "sarah@example.com"
This info gets attached to every commit you make. Don't skip it — you'll regret it when your commits show up as "Unknown Author."
Part 3: Your First Repository
A repository (or "repo") is just a folder that Git is tracking.
Let's make one from scratch.
# Create a new folder mkdir my-first-project cd my-first-project # Tell Git to start tracking this folder git init
You'll see something like:
Initialized empty Git repository in /Users/sarah/my-first-project/.git/
That .git folder? That's where Git stores everything — every version of every file, every commit, the whole history. Don't touch it. Don't delete it.
Your First File
echo "# My First Project" > README.md
Now check what Git sees:
git status
On branch main Untracked files: (use "git add <file>..." to include in what will be committed) README.md nothing added to commit but untracked files present
Git sees your file but isn't tracking it yet. It's like a stranger standing at your door — Git notices them but hasn't let them in.
Part 4: The Three Stages of Git (This is the Key Concept)
This trips up almost everyone at first. Git has three stages:
Your Files → Staging Area → Repository (History) (Working) (Index) (Commits)
Think of it like packing a box to ship:
- Working directory — your desk, stuff scattered everywhere
- Staging area — things you've put IN the box, but haven't sealed it yet
- Repository — the sealed, shipped box. Permanent record.
Stage Your File
git add README.md
Or to add everything at once:
git add .
Check status again:
git status
Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: README.md
It's in the box. Now seal it.
Commit (Save to History)
git commit -m "Add README file"
The -m flag is your message. Write something meaningful. "fix stuff" is useless. "Fix login button not responding on mobile" is helpful.
[main (root-commit) 3f4a1b2] Add README file 1 file changed, 1 insertion(+) create mode 100644 README.md
Congratulations. You just made your first commit. That change is now permanently recorded in Git's history.
View Your History
git log
commit 3f4a1b2c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0 Author: Sarah Johnson <sarah@example.com> Date: Mon May 19 10:30:00 2025 Add README file
That long string of letters and numbers? That's the commit hash — a unique ID for that exact snapshot of your code. You can always come back to it.
Part 5: Branches — The Heart of Git
Here's where Git gets powerful.
Imagine you're building a feature for your app — let's say a login page. It's going to take a week. Meanwhile, your teammate needs to fix a bug in production. If you're both working on the same files, you'll constantly be stepping on each other.
Branches solve this. A branch is like a parallel universe of your code.
main branch: A --- B --- C \ feature branch: D --- E --- F
You go off and work in your own world. When you're done, you bring your changes back to main.
Create a New Branch
git branch feature/login-page
Switch to It
git checkout feature/login-page
Or do both at once (the shortcut everyone uses):
git checkout -b feature/login-page
You're now on a new branch. Check which branch you're on:
git branch
* feature/login-page main
The * marks your current branch.
Make Changes on the Branch
echo "Login page HTML goes here" > login.html git add login.html git commit -m "Add login page skeleton"
This commit only exists on feature/login-page. Your main branch doesn't know about it yet.
Switch Back to Main
git checkout main
Notice login.html is gone from your folder. It's not deleted — it's just not part of main yet. It still exists on feature/login-page.
Part 6: Merging — Bringing Work Back Together
You've finished your login page. Time to bring it back to main.
# Make sure you're on main git checkout main # Merge the feature branch into main git merge feature/login-page
Updating 3f4a1b2..8c9d0e1 Fast-forward login.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 login.html
Done. Your login page is now part of main.
What Are Merge Conflicts?
Sometimes two people edited the same line of the same file. Git can't guess which version to keep — it asks you to decide.
<<<<<<< HEAD <h1>Welcome Back</h1> ======= <h1>Sign In to Continue</h1> >>>>>>> feature/login-page
- Everything between
<<<<<<< HEADand=======is what's in your current branch (main) - Everything between
=======and>>>>>>> feature/login-pageis what's in the branch you're merging in
You have to manually edit the file, pick what you want (or combine them), remove those <<<<, ====, >>>> markers, then:
git add login.html git commit -m "Resolve merge conflict in login page heading"
Conflicts feel scary the first few times. They're not. You're just making a decision.
Part 7: Rebase — The Cleaner Alternative
This one confuses people. Let's demystify it.
When you merge, you create a new "merge commit" that connects the two branches. The history looks like a messy graph.
When you rebase, you replay your commits on top of the latest main. The history stays clean and linear.
Before rebase:
main: A --- B --- C \ feature: D --- E
After git rebase main on feature branch:
main: A --- B --- C \ feature: D' --- E'
The commits D and E got "replayed" on top of C. They're technically new commits (hence D' and E'), but the changes are identical.
How to Do It
# You're on feature/login-page git rebase main
This says: "Take all my commits, and pretend I branched off the latest main, not the old one."
Merge vs Rebase — Which One?
- Merge when working with others and want to preserve the exact history
- Rebase when you want a clean, linear history and you're the only one on the branch
Golden rule: Never rebase a branch that other people are also working on. You're rewriting history, and it'll mess up their copies.
Part 8: GitHub — Putting It Online
Now let's connect your local repo to GitHub.
Create a GitHub Account
Go to github.com and sign up. Free tier is more than enough to start.
Create a New Repository on GitHub
- Click the
+icon top right → "New repository" - Name it
my-first-project - Leave it public
- Don't initialize with a README (you already have one)
- Click "Create repository"
GitHub will show you commands. Use these:
# Add GitHub as the remote "origin" for your local repo git remote add origin https://github.com/yourusername/my-first-project.git # Push your code up git push -u origin main
-u origin main sets the default — next time you can just type git push and it'll know where to send it.
Refresh your GitHub page. Your code is online.
Part 9: Clone — Getting Someone Else's Code
Found an interesting project on GitHub? Want to download it?
git clone https://github.com/torvalds/linux.git
This downloads the entire repository — all code, all history, all branches — to your machine. (Don't actually clone the Linux kernel. It's massive. Use a smaller project for practice.)
After cloning, cd into the folder and you're ready to go.
Part 10: Pull Requests — How Real Teams Work
This is the thing GitHub added that changed open-source collaboration forever.
A Pull Request (PR) is not a Git feature — it's a GitHub feature. It's a formal way of saying:
"Hey, I made some changes on this branch. Can someone review them before we merge into main?"
This is how every professional team works. Nobody pushes directly to main. You make a branch, do your work, open a PR, someone reviews it, then it gets merged.
The Workflow
Step 1: Fork (if it's someone else's repo)
Forking creates your own copy of someone's repository. You can't push to their repo directly, but you can push to your fork.
Click the "Fork" button on any GitHub repo.
Step 2: Clone your fork
git clone https://github.com/yourusername/forked-repo.git cd forked-repo
Step 3: Create a branch for your change
git checkout -b fix/typo-in-readme
Step 4: Make your changes, commit them
# Edit README.md git add README.md git commit -m "Fix typo: 'recieve' → 'receive' in README"
Step 5: Push your branch to GitHub
git push origin fix/typo-in-readme
Step 6: Open a Pull Request
Go to your fork on GitHub. You'll see a yellow banner: "Compare & pull request." Click it.
- Write a clear title
- Explain what you changed and why in the description
- Click "Create pull request"
Step 7: Review and Merge
The repo owner gets notified. They can:
- Leave comments on specific lines
- Request changes
- Approve and merge
If they ask for changes, you just push more commits to the same branch. The PR updates automatically.
Part 11: Multiple People Working Together
Let's say you and three teammates are building an app. Here's the workflow that actually works:
The Setup
# Everyone clones the same repo git clone https://github.com/team/app.git
The Daily Workflow
Morning — get latest changes:
git checkout main git pull origin main
git pull = git fetch (download) + git merge (integrate). Always pull before starting work.
Start your task:
git checkout -b feature/user-profile
Work, commit often:
git add . git commit -m "Add profile picture upload component" # More work... git commit -m "Add profile bio editing with character limit"
Commit small and often. Every commit should be a working state. "WIP" commits are fine locally — just don't leave them when you open a PR.
Before opening a PR — sync with main:
git checkout main git pull origin main git checkout feature/user-profile git rebase main
This makes sure your PR won't have conflicts when merged.
Push and open PR:
git push origin feature/user-profile
Then open the PR on GitHub.
What If Two People Edited the Same File?
This happens all the time. Git will try to auto-merge. If it can't, you get a conflict (covered in Part 6). Whoever opens their PR second will have to resolve it.
This is why communication matters. Let your team know what you're working on. Use GitHub Issues or any project tracker to claim tasks.
Part 12: The Commands You'll Use Every Day
Here's the honest truth — 90% of your day-to-day is these commands:
# Check status of your files git status # Stage everything git add . # Commit with a message git commit -m "Your message here" # Push to GitHub git push # Pull latest from GitHub git pull # Create and switch to new branch git checkout -b branch-name # Switch to existing branch git checkout branch-name # See all branches git branch # Merge a branch into current git merge branch-name # See history git log --oneline
git log --oneline is the compact version. Looks like:
8c9d0e1 Add login page skeleton 3f4a1b2 Add README file
Much easier to read than the full log.
Part 13: Undoing Mistakes
We all make mistakes. Here's how to un-make them.
Undo the Last Commit (Keep the Changes)
git reset --soft HEAD~1
This removes the commit but keeps your changes staged. Useful when you committed too early.
Undo the Last Commit (Remove the Changes Too)
git reset --hard HEAD~1
Warning: This is permanent. Your changes are gone. Only use this if you're absolutely sure.
Undo Staged Changes (Unstage a File)
git restore --staged filename.txt
Discard Changes to a File
git restore filename.txt
This throws away any unsaved changes to that file and goes back to the last committed version.
You Committed to the Wrong Branch
# You're on main but committed there accidentally # Copy the commit hash from git log git log --oneline # e.g., the commit is abc1234 # Move to the right branch git checkout feature/my-feature git cherry-pick abc1234 # Go back to main and remove it git checkout main git reset --hard HEAD~1
cherry-pick grabs a single commit from anywhere and applies it to your current branch. Very handy.
Part 14: Real Example — A Full Collaborative Session
Let's walk through a complete realistic scenario.
The Team: Sarah (frontend), Marcus (backend), Priya (lead)
The Task: Sarah needs to add a "dark mode" toggle.
# Sarah starts her day git checkout main git pull origin main # Gets: "Already up to date." or pulls in Marcus's latest backend changes. # Sarah creates her branch git checkout -b feature/dark-mode-toggle # Sarah works on it for a few hours... # She edits: src/components/ThemeToggle.jsx, src/styles/dark.css git add src/components/ThemeToggle.jsx git add src/styles/dark.css git commit -m "Add ThemeToggle component with sun/moon icons" # More work git commit -m "Add dark mode CSS variables and body class toggle" # Sarah is done. She syncs with main before pushing. git checkout main git pull origin main git checkout feature/dark-mode-toggle git rebase main # No conflicts! Great. # Push git push origin feature/dark-mode-toggle
Sarah goes to GitHub, opens a PR:
Title: "Add dark mode toggle"
Description:
## What does this PR do? Adds a toggle button in the navbar that switches between light/dark mode. User preference is saved to localStorage. ## Screenshots [image of toggle in light mode] [image of toggle in dark mode] ## Testing - Tested on Chrome, Firefox, Safari - Toggle persists on page refresh
Priya reviews it. She leaves a comment: "Love it! Can we add a keyboard shortcut too? Accessibility thing."
Sarah adds it:
git add src/components/ThemeToggle.jsx git commit -m "Add keyboard shortcut (Ctrl+Shift+D) for dark mode toggle" git push origin feature/dark-mode-toggle
The PR automatically updates. Priya approves. Clicks "Merge pull request."
Dark mode is in main. Everyone pulls the next morning and gets it.
This is the full loop. This is how it works.
Part 15: .gitignore — What NOT to Track
Not everything should go into your repo. Secrets, generated files, local configs — these should stay off GitHub.
Create a .gitignore file in your project root:
# .gitignore # Environment variables (NEVER commit these) .env .env.local # Node.js node_modules/ # Build output dist/ build/ # OS files .DS_Store # Mac Thumbs.db # Windows # Editor files .vscode/ .idea/
Any file or folder listed here will be completely ignored by Git. It won't show up in git status and it won't get committed.
Important: If you accidentally committed a .env file with real secrets, assume those secrets are compromised. Rotate them immediately, even if you delete the file afterward — the history still has it.
Quick Reference Cheatsheet
| Task | Command |
|---|---|
| Initialize repo | git init |
| Clone a repo | git clone <url> |
| Check status | git status |
| Stage all changes | git add . |
| Commit | git commit -m "message" |
| Push | git push |
| Pull | git pull |
| New branch | git checkout -b branch-name |
| Switch branch | git checkout branch-name |
| List branches | git branch |
| Merge branch | git merge branch-name |
| Rebase | git rebase main |
| View history | git log --oneline |
| Unstage file | git restore --staged file |
| Discard changes | git restore file |
| Undo last commit | git reset --soft HEAD~1 |
Where to Go From Here
You now know enough to:
- Track your own projects with Git
- Collaborate with a team using branches and PRs
- Contribute to open-source projects on GitHub
Things to explore next:
git stash— temporarily shelf your work to switch branches quickly- GitHub Actions — automate tests and deployments when you push code
git bisect— find which commit introduced a bug- Conventional Commits — a standard for writing consistent commit messages
The best way to learn Git is to use it. Break things. Recover them. That's actually how Linus designed it — hard to permanently lose data, easy to experiment.
Built with frustration, coffee, and the belief that documentation shouldn't put you to sleep.