init, clone, add, commit, status, log, diffgit initstatus, add, commit, log, diffreset, revert, restoreGit is a distributed version control system created by Linus Torvalds in 2005 to manage the Linux kernel โ a project with thousands of contributors worldwide. It tracks every change to every file in your project, forever.
Here's what Git gives you:
This confuses every beginner. Here's the simplest explanation:
| Git | GitHub |
|---|---|
| A tool that runs on your computer | A website (cloud service) |
| Manages version history locally | Hosts copies of your repos online |
| Works completely offline | Requires internet to sync |
| Free and open-source | Free for public repos; paid plans for private teams |
| Created by Linus Torvalds (2005) | Founded by Tom Preston-Werner (2008) |
Analogy: Git is your engine โ it does the real work of tracking changes. GitHub is a parking lot where you share your car (repo) with others. You need the engine to drive; the parking lot just makes it easy to park together.
| OS | How to Install | Verify |
|---|---|---|
| Windows | Download from gitforwindows.org. Run the installer (defaults are fine). | git --version |
| macOS | Open terminal and type git --version. If not installed, it prompts you to install Xcode Command Line Tools. |
git --version |
| Linux (Ubuntu/Debian) | sudo apt update && sudo apt install git -y |
git --version |
Git stamps every commit with your name and email. Set them once and forget them:
git config --global user.name "Your Full Name" git config --global user.email "[email protected]"
Git sometimes opens a text editor (for commit messages, merge descriptions, etc.). Set it to VS Code (or your preferred editor):
git config --global core.editor "code --wait"
git config --list
git config --global commands again with the correct values. Git overwrites the old values. Past commits still show the old identity โ but all future commits will use the new one.
What is the difference between Git and GitHub?
git init BeginnerA repository (or "repo") is simply a folder that Git is watching. To turn any folder into a Git repository:
mkdir my-first-repo cd my-first-repo git init
That's it. Git creates a hidden .git/ folder inside your project. This folder is the engine room โ it contains the entire history, all branches, all configuration. Never touch it directly.
ls -la (or dir /a on Windows). You'll see the .git/ directory. Delete it, and your repo is no longer a repo โ just a regular folder again.
git statusThe most-used command in Git. Run it constantly to stay oriented:
git status
Right now, it tells you: "No commits yet" and lists your untracked files (if any). We'll fix that next.
What does git init do?
git init creates the .git/ folder that Git uses to store all version history, branches, and configuration.This is the single most important concept in Git. Understand this, and everything else clicks into place.
Git manages your files across three "trees":
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ Working โ โ Staging โ โ Repository โ โ Directory โ โโโถ โ Area โ โโโถ โ (.git/ history) โ โ โ โ (Index) โ โ โ โ Your editor โ โ "git add" โ โ "git commit" โ โ changes here โ โ prepares here โ โ saves forever โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
| Tree | What It Is | Command to Move Forward |
|---|---|---|
| 1. Working Directory | The actual files you see and edit in your editor. Messy, alive, changing. | You edit files here naturally. |
| 2. Staging Area (Index) | A "preview" area where you gather changes before committing. You decide exactly which changes go into the next snapshot. | git add <file> |
| 3. Repository (History) | The permanent record. Every commit here is immortal โ it stays in the log forever. | git commit -m "message" |
Which Git command moves changes from the Working Directory to the Staging Area?
git add stages changes. git commit then moves them from staging to the permanent history (repository).status, add, commit, log, diff BeginnerLet's create a file and walk through the cycle.
echo "Hello, Git!" > README.md
git status
Git says README.md is "untracked" โ it sees the file but isn't watching it yet.
git add README.md
Now git status shows it as "Changes to be committed" โ staged and ready.
git commit -m "Add README with greeting"
git log
You should see your first commit: a unique hash, your name, your email, the timestamp, and your message.
git log โ Your Project's Diarycommit 1a2b3c4d5e6f7g8h9i0j... Author: Your Name <[email protected]> Date: Thu Jul 9 14:30:00 2026 +0530 Add README with greeting
Every commit has a unique 40-character hash (like a fingerprint). You use this hash to reference the commit when you need to travel back in time.
Useful variants:
git log --oneline # Compact view: one line per commit git log --graph # Show branch structure visually git log -p # Show the actual changes (diff) for each commit
git diff โ See Changes Before You StageBefore staging, see exactly what changed:
# View unstaged changes git diff # View staged changes (what will be committed) git diff --staged
What does git log --oneline do?
git log --oneline shows each commit on a single line with just the abbreviated hash and message โ perfect for scanning.You edit 3 files (a.py, b.py, c.py). You only want to commit a.py and b.py because c.py isn't finished. What do you do?
git add a.py b.py), then commit. c.py stays in the working directory, untouched. This is exactly why the staging area exists.A branch is a movable pointer to a commit. When you create a new branch, you're creating a parallel universe where you can experiment freely without affecting the main code.
main โโโโโโโโโโ
โ (main is here)
feature โโโโโโโโโโโโโโโโ
(you branch off here) (new commits only on feature)
# List branches (* = current branch) git branch # Create a new branch git branch feature-login # Switch to it git checkout feature-login # Create AND switch in one command (modern way) git checkout -b feature-login
git checkout -b add-footer
echo "<footer>ยฉ 2026 Our Team</footer>" > footer.html git add footer.html git commit -m "Add footer to all pages"
git checkout main
Notice: footer.html is gone from your working directory! It only exists on the add-footer branch. Your main branch is untouched.
master in older versions and main in newer ones (since 2021). Both work identically. This tutorial uses main, but if your system uses master, just substitute the name.
You create a branch feature-x and make 3 commits on it. Then you switch back to main. Where are those 3 commits?
feature-x stay there until you merge them into main.Merging combines the work from two branches. When your feature is ready, you merge it back into main.
# Switch to the branch you want to merge INTO git checkout main # Merge the feature branch INTO current branch git merge add-footer
If both branches changed the same lines of the same file, Git produces a merge conflict. It doesn't know which version to keep, so it asks you to decide.
Git marks the conflict in the file:
<<<<<<< HEAD This line was added on main ======= This line was added on the feature branch >>>>>>> add-footer
Your job: Edit the file to keep the correct version (or a combination of both), remove the conflict markers, then:
git add <file> git commit -m "Resolve merge conflict between main and add-footer"
You are on main and run git merge feature-nav. What happens?
feature-nav into the current branch (main). The feature branch still exists unless you delete it with git branch -d feature-nav.So far, everything has been local โ on your machine. Now let's put it on GitHub so you can share it, back it up, and collaborate.
my-first-repo (the same name as your local project)A remote is a URL linking your local repo to GitHub. The conventional name is origin.
git remote add origin https://github.com/YOUR_USERNAME/my-first-repo.git
git push -u origin main
The -u flag sets upstream tracking โ after this, you can simply type git push and git pull without specifying the remote and branch every time.
repo scope. Copy it, paste it when prompted. Save it somewhere safe.
What does git remote add origin <URL> do?
git remote add just stores the URL. It doesn't transfer any data. git push is what actually uploads your commits.Once your local repo is connected to GitHub, you have three commands to sync changes:
| Command | Direction | What It Does |
|---|---|---|
git push |
Local โ Remote | Uploads your commits to GitHub. Others can now see your work. |
git pull |
Remote โ Local | Downloads others' commits AND merges them into your current branch. (git fetch + git merge in one step) |
git fetch |
Remote โ Local (safe) | Downloads others' commits but does NOT merge. Lets you inspect changes before integrating. |
# Step 1: Get latest info without merging git fetch origin # Step 2: See what's different git log main..origin/main # Step 3: Now merge (or use pull for a quick shortcut) git pull origin main
Which command downloads remote changes WITHOUT merging them into your working files?
git fetch downloads the data but doesn't touch your working directory. Use it when you want to inspect changes before merging. git pull = git fetch + git merge.A Pull Request (PR) is GitHub's mechanism for proposing changes. Instead of merging directly to main, you:
maingit checkout -b add-contact-form
echo "<form>Contact us...</form>" > contact.html git add contact.html git commit -m "Add contact form page"
git push -u origin add-contact-form
Go to your repo on GitHub. You'll see a banner: "add-contact-form had recent pushes". Click Compare & pull request. Add a title and description, then click Create pull request.
Since you're the sole contributor, click Merge pull request. GitHub merges your branch into main on the remote.
git checkout main git pull origin main
Your local main now has the latest code. Delete the feature branch: git branch -d add-contact-form
In a team, step 4 is where the magic happens โ teammates review your code, catch bugs, and discuss improvements before the code lands in main.
Forking is how you contribute to a repository you don't own. A fork is your personal copy of someone else's repo on GitHub.
facebook/react)git clone https://github.com/YOUR_USERNAME/react.git cd react
git remote add upstream https://github.com/facebook/react.git
git fetch upstream git checkout main git merge upstream/main
reset, revert, restore IntermediateEveryone makes mistakes. Git has three different tools to undo things, depending on where the mistake is.
| If you... | Command | What it does |
|---|---|---|
| Changed a file but haven't staged it yet | git restore <file> |
Discards changes in working directory โ file goes back to last commit state |
Already staged a file (git add) but want to unstage |
git restore --staged <file> |
Unstages the file (keeps your edits, just removes from staging area) |
| Committed but want to undo the commit (keep changes) | git reset --soft HEAD~1 |
Removes the commit, keeps changes staged |
| Committed but want to completely discard the commit AND changes | git reset --hard HEAD~1 |
โ ๏ธ Destructive! Removes commit and all its changes. Use with extreme caution. |
| Already pushed a bad commit to GitHub | git revert <commit-hash> |
Creates a new commit that undoes the old one. Safe to push โ doesn't rewrite history. |
reset --hard on public commits
If you've already pushed a commit to GitHub, use git revert instead. reset --hard rewrites history, which breaks everyone else's repos if they've pulled your bad commit. revert is the safe, collaborative undo.
You accidentally pushed a broken commit to GitHub. What's the safest way to undo it without disrupting your teammates?
git revert creates a new commit that undoes the bad one. It preserves history and is safe to push. Force-pushing a reset would erase history and break your teammates' clones.Some files should never be committed to Git:
.env files with API keys, passwords, database URLsnode_modules/, dist/, .next/, compiled binaries.DS_Store (macOS), Thumbs.db (Windows).vscode/, .idea/ (IntelliJ), *.swp (Vim)*.log, .cache/, __pycache__/Create a .gitignore file in your project root listing patterns to exclude:
# .gitignore node_modules/ .env *.log .DS_Store dist/ __pycache__/ *.pyc
Then commit it:
git add .gitignore git commit -m "Add .gitignore"
.gitignore won't stop Git from tracking it. You must first remove it: git rm --cached <file>.
You accidentally committed a file secret.env two weeks ago. You add it to .gitignore now. Will Git stop tracking it?
.gitignore only prevents Git from automatically adding untracked files. To stop tracking an already-tracked file, use git rm --cached (which removes it from the index but keeps it on disk).Let's put everything together. From scratch, build a small HTML project and push it to GitHub โ using branches, commits, and a pull request.
mkdir recipe-site cd recipe-site git init echo "# My Recipe Collection" > README.md git add README.md git commit -m "Initial commit with README"
cat > index.html << 'EOF'My Recipes Welcome to My Recipe Collection
Delicious recipes from around the world.
EOF git add index.html git commit -m "Add homepage skeleton"
git checkout -b add-recipe-page
cat > pancakes.html << 'EOF'Pancakes Recipe Fluffy Pancakes
Ingredients
Mix, pour, flip, enjoy!
EOF git add pancakes.html git commit -m "Add pancakes recipe page"sed -i '/<\/ul>/a Pancakes' index.html # If sed doesn't work on Windows, manually add: Pancakes git add index.html git commit -m "Add pancakes link to homepage"
git checkout main git merge add-recipe-page git branch -d add-recipe-page
# Create "recipe-site" on GitHub (no README, no .gitignore) git remote add origin https://github.com/YOUR_USERNAME/recipe-site.git git push -u origin main
Refresh your repo page on GitHub. You should see all files, all commits, and the full history. You just shipped a real project with proper version control!
| Category | Command | What It Does |
|---|---|---|
| Setup | git config --global user.name "Name" | Set your name for all commits |
git init | Create a new repo in current folder | |
git clone <url> | Download a repo from GitHub | |
| Daily Work | git status | Check what's changed |
git add <file> | Stage changes | |
git commit -m "msg" | Save staged changes as a snapshot | |
git log --oneline | View history compactly | |
git diff | See unstaged changes | |
| Branching | git branch <name> | Create a branch |
git checkout <branch> | Switch to a branch | |
git checkout -b <name> | Create and switch in one step | |
git merge <branch> | Merge branch into current | |
git branch -d <name> | Delete a branch (after merge) | |
| Sync | git push origin main | Upload commits to GitHub |
git pull origin main | Download + merge others' commits | |
git fetch origin | Download without merging | |
git remote add origin <url> | Link local repo to GitHub | |
| Undo | git restore <file> | Discard unstaged changes |
git restore --staged <file> | Unstage a file | |
git revert <hash> | Safe undo (creates new commit) | |
git reset --soft HEAD~1 | Undo last commit, keep changes |
git revert on public commits, not reset --hard. Never rewrite history that others have pulled..gitignore early โ add it in your first commit to avoid accidentally tracking secrets or build artifacts.pull โ edit โ add โ commit โ push. Master these, and you master 90% of Git.