Git for Beginners: Basics and Essential Commands
What is Git?
Imagine you're writing a book. Every time you make changes, you save a new copy with a name like "MyBook_v1.doc", "MyBook_v2_final.doc", "MyBook_v2_ACTUALLY_final.doc", "MyBook_v3_this_time_for_real.doc"...
Sound familiar? This gets messy fast!
Git is a smarter way to track changes to your files. Instead of creating multiple copies, Git takes "snapshots" of your project at different points in time. You can:
See exactly what changed between versions
Go back to any previous version
Work on new features without breaking your working code
Collaborate with other developers without overwriting each other's work
Simple definition:
Git is a version control system that tracks changes to your files over time, like an unlimited undo button with superpowers.
Traditional approach (messy):
MyProject_v1/
MyProject_v2/
MyProject_final/
MyProject_final_FINAL/
MyProject_final_FINAL_v3/
Git approach (clean):
MyProject/
└── .git/ (all history stored here)
Why Git is Used
1. Track Changes Over Time
Git remembers every change you make and who made it.
Version 1 (Monday): Added login feature
Version 2 (Tuesday): Fixed login bug
Version 3 (Wednesday): Added password reset
↓
You can go back to any version anytime!
2. Undo Mistakes Safely
Broke something? No problem – just go back to when it worked.
Working Code → Made Changes → Everything Broke
↓
Git: "Here's your working code back!"
3. Collaborate Without Chaos
Multiple developers can work on the same project simultaneously.
Developer A working on: Login feature
Developer B working on: Payment system
↓
Git merges both changes without conflicts
4. Experiment Safely with Branches
Create a separate "branch" to try new ideas without affecting your main code.
Main Code (stable)
↓
├─── Experimental Feature Branch (safe to break things)
│
└─── When ready, merge back into main
5. Industry Standard
Almost every tech company and open-source project uses Git. Learning Git is essential for any developer.
Git Basics and Core Terminologies
Before diving into commands, let's understand the key concepts:
1. Repository (Repo)
A repository is a folder that Git is tracking. It contains all your project files plus a hidden .git folder where Git stores all the history.
MyProject/
├── index.html
├── style.css
├── script.js
└── .git/ ← Git's storage (don't touch this!)
└── (all version history lives here)
Types of repositories:
Local repository: On your computer
Remote repository: On a server (like GitHub, GitLab)
2. Commit
A commit is a snapshot of your project at a specific point in time. Think of it as a save point in a video game.
Commit 1: "Added homepage"
Commit 2: "Fixed typo in header"
Commit 3: "Added contact form"
↓
Each commit has a unique ID and message
Every commit includes:
What changed
Who made the change
When it was made
A message describing the change
3. Branch
A branch is an independent line of development. The default branch is usually called main (or master in older repos).
main branch: A --- B --- C --- D
\
feature branch: X --- Y --- Z
Think of branches as parallel universes where you can experiment without affecting the main timeline.
4. HEAD
HEAD is a pointer that tells you where you currently are in your Git history. Usually, it points to the latest commit on your current branch.
Commits: A --- B --- C --- D
↑
HEAD (you are here)
5. Staging Area (Index)
The staging area is a middle ground between your working files and a commit. It's where you prepare changes before committing them.
Working Directory → Staging Area → Repository
(your files) (prepared) (committed)
The Git Workflow: The Three States
Git has three main states that your files can be in:
┌─────────────────────────────────────────────────────────────┐
│ THE GIT WORKFLOW │
└─────────────────────────────────────────────────────────────┘
1. WORKING DIRECTORY
(Your actual files)
├── index.html (modified)
├── style.css (new file)
└── script.js (unchanged)
│
│ git add <file>
↓
2. STAGING AREA
(Files ready to be committed)
├── index.html (staged)
└── style.css (staged)
│
│ git commit -m "message"
↓
3. REPOSITORY (.git directory)
(Permanent snapshot saved)
└── Commit: "Added homepage and styles"
Visual Flow:
┌──────────────────┐
│ Working Directory│ ← You edit files here
│ │
│ • Modified files │
│ • New files │
│ • Deleted files │
└──────────────────┘
│
│ git add
↓
┌──────────────────┐
│ Staging Area │ ← Prepare files for commit
│ │
│ • Ready to commit│
└──────────────────┘
│
│ git commit
↓
┌──────────────────┐
│ Repository │ ← Permanent history
│ (.git directory) │
│ │
│ • All commits │
│ • All branches │
└──────────────────┘
Common Git Commands
Let's go through the essential Git commands with practical examples.
1. git init – Create a New Repository
Purpose: Initialize Git in a folder to start tracking changes.
mkdir MyProject
cd MyProject
git init
What happens:
Before:
MyProject/
After:
MyProject/
└── .git/ ← Git initialized!
Output:
Initialized empty Git repository in /Users/you/MyProject/.git/
2. git status – Check Current State
Purpose: See which files are modified, staged, or untracked.
git status
Example output:
On branch main
Untracked files:
(use "git add <file>..." to include in what will be committed)
index.html
style.css
nothing added to commit but untracked files present
What it means:
Untracked: Git sees these files but isn't tracking them yet
Modified: File changed since last commit
Staged: File ready to be committed
3. git add – Stage Files
Purpose: Add files to the staging area (prepare for commit).
# Add a specific file
git add index.html
# Add multiple files
git add index.html style.css
# Add all files
git add .
Visual:
Working Directory Staging Area
├── index.html → ├── index.html ✓
├── style.css → └── style.css ✓
└── script.js
After git add .:
git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: index.html
new file: style.css
4. git commit – Save Snapshot
Purpose: Save staged changes as a commit with a message.
git commit -m "Add homepage and styles"
The -m flag: Stands for "message" – every commit needs a descriptive message!
Good commit messages:
✅ "Add user login feature"
✅ "Fix navigation bar alignment"
✅ "Update README with installation steps"
❌ "Update stuff"
❌ "Changes"
❌ "Fix"
Visual:
Staging Area Repository
├── index.html → Commit: "Add homepage and styles"
└── style.css ├── index.html
└── style.css
5. git log – View Commit History
Purpose: See all commits made in the repository.
git log
Output:
commit a1b2c3d4e5f6g7h8i9j0 (HEAD -> main)
Author: John Doe <john@example.com>
Date: Fri Jan 31 10:30:00 2026 +0600
Add homepage and styles
commit k9l8m7n6o5p4q3r2s1t0
Author: John Doe <john@example.com>
Date: Thu Jan 30 15:20:00 2026 +0600
Initial commit
Simpler view:
git log --oneline
Output:
a1b2c3d (HEAD -> main) Add homepage and styles
k9l8m7n Initial commit
Visual history:
k9l8m7n: "Initial commit"
↓
a1b2c3d: "Add homepage and styles" ← HEAD (you are here)
6. git branch – Manage Branches
Purpose: Create, list, or delete branches.
List all branches:
git branch
Output:
* main
(The * shows your current branch)
Create a new branch:
git branch feature-login
Visual:
main: A --- B --- C
\
feature-login: (points to C, ready to diverge)
List branches again:
git branch
feature-login
* main
7. git checkout / git switch – Change Branches
Purpose: Switch to a different branch.
Old way:
git checkout feature-login
New way (Git 2.23+):
git switch feature-login
Create and switch in one command:
git checkout -b feature-payment
# or
git switch -c feature-payment
Visual:
Before:
main: A --- B --- C ← HEAD
\
feature-login:
After switching:
main: A --- B --- C
\
feature-login: ← HEAD (now here)
8. git merge – Combine Branches
Purpose: Merge changes from one branch into another.
Scenario: You've finished working on feature-login and want to merge it into main.
# Switch to main
git switch main
# Merge feature-login into main
git merge feature-login
Visual:
Before merge:
main: A --- B --- C
\
feature-login: D --- E
After merge:
main: A --- B --- C --- F (merge commit)
\ /
feature-login: D --------- E
9. git clone – Copy a Repository
Purpose: Download a repository from a remote server (like GitHub).
git clone https://github.com/username/repository.git
What happens:
Remote (GitHub) Your Computer
MyProject/ → MyProject/
├── files ├── files
└── .git/ └── .git/
10. git pull – Get Latest Changes
Purpose: Download changes from remote repository and merge them.
git pull origin main
Visual:
Remote: A --- B --- C --- D
Local: A --- B --- C
↓ git pull
Local: A --- B --- C --- D (now updated)
11. git push – Upload Changes
Purpose: Send your commits to a remote repository.
git push origin main
Visual:
Local: A --- B --- C --- D
↓ git push
Remote: A --- B --- C --- D (now updated)
12. git diff – See Changes
Purpose: See what changed in files before staging.
# See unstaged changes
git diff
# See staged changes
git diff --staged
Example output:
diff --git a/index.html b/index.html
--- a/index.html
+++ b/index.html
@@ -1,3 +1,4 @@
<html>
<head>
+ <title>My Website</title>
</head>
Lines with + are additions, - are deletions.
Basic Developer Workflow: A Complete Example
Let's walk through a typical workflow from scratch:
Scenario: Creating a Simple Website Project
Step 1: Create and Initialize Project
mkdir my-website
cd my-website
git init
Step 2: Create Files
echo "<!DOCTYPE html><html><head><title>My Site</title></head><body><h1>Hello World</h1></body></html>" > index.html
echo "body { font-family: Arial; }" > style.css
Step 3: Check Status
git status
Untracked files:
index.html
style.css
Step 4: Stage Files
git add .
Step 5: Commit
git commit -m "Initial commit: Add homepage and basic styles"
Step 6: Make Changes
echo "<script>console.log('Hello!');</script>" >> index.html
Step 7: Check What Changed
git status
Changes not staged for commit:
modified: index.html
git diff
(Shows the exact line added)
Step 8: Stage and Commit Changes
git add index.html
git commit -m "Add JavaScript console log"
Step 9: Create a Feature Branch
git switch -c feature-contact-form
Step 10: Work on Feature
echo "<form><input type='email' placeholder='Email'><button>Submit</button></form>" >> index.html
git add index.html
git commit -m "Add contact form"
Step 11: Merge Back to Main
git switch main
git merge feature-contact-form
Step 12: View History
git log --oneline --graph
Output:
* d4e5f6g (HEAD -> main) Merge feature-contact-form
|\
| * c3d4e5f (feature-contact-form) Add contact form
|/
* b2c3d4e Add JavaScript console log
* a1b2c3d Initial commit: Add homepage and basic styles
Visual Diagram: Complete Git Workflow
┌─────────────────────────────────────────────────────────────┐
│ COMPLETE GIT WORKFLOW │
└─────────────────────────────────────────────────────────────┘
1. Initialize Project
┌──────────────┐
│ git init │
└──────────────┘
↓
Creates .git/ directory
2. Create/Edit Files
┌──────────────────┐
│ Working Directory│
│ • index.html │
│ • style.css │
└──────────────────┘
↓
git status (see untracked files)
3. Stage Changes
┌──────────────┐
│ git add . │
└──────────────┘
↓
┌──────────────────┐
│ Staging Area │
│ ✓ index.html │
│ ✓ style.css │
└──────────────────┘
↓
git status (see staged files)
4. Commit
┌─────────────────────────────┐
│ git commit -m "message" │
└─────────────────────────────┘
↓
┌──────────────────┐
│ Repository │
│ Commit A │
└──────────────────┘
↓
git log (view history)
5. Create Branch
┌────────────────────────────┐
│ git switch -c feature │
└────────────────────────────┘
↓
main: A
\
feature: (ready to diverge)
6. Work on Feature
↓
main: A
\
feature: B --- C
7. Merge Back
┌────────────────────────────┐
│ git switch main │
│ git merge feature │
└────────────────────────────┘
↓
main: A --- D (merge)
\ /
feature: B-C
8. Push to Remote (if using GitHub)
┌────────────────────────────┐
│ git push origin main │
└────────────────────────────┘
↓
Local → Remote (GitHub/GitLab)
Commit History Visualization
┌─────────────────────────────────────────────────────────────┐
│ COMMIT HISTORY FLOW │
└─────────────────────────────────────────────────────────────┘
Time →
Commit 1 Commit 2 Commit 3
├─────────────────┬────├─────────────────┬────├─────────────────┐
│ ID: a1b2c3d │ │ ID: d4e5f6g │ │ ID: h7i8j9k │
│ Message: │ │ Message: │ │ Message: │
│ "Initial commit"│ │ "Add login" │ │ "Fix bug" │
│ Author: John │ │ Author: John │ │ Author: Jane │
│ Date: Jan 30 │ │ Date: Jan 31 │ │ Date: Jan 31 │
├─────────────────┴────├─────────────────┴────├─────────────────┤
│ Files: │ Files: │ Files: │
│ + README.md │ + login.js │ M login.js │
│ + index.html │ M index.html │ │
└──────────────────────┴──────────────────────┴──────────────────┘
↑
HEAD
Legend:
+= File addedM= File modified-= File deleted
Essential Git Commands Quick Reference
┌─────────────────┬──────────────────────────────────────────┐
│ Command │ What it does │
├─────────────────┼──────────────────────────────────────────┤
│ git init │ Initialize a new Git repository │
│ git status │ Check status of files │
│ git add <file> │ Stage specific file │
│ git add . │ Stage all changes │
│ git commit -m │ Commit staged changes │
│ git log │ View commit history │
│ git log --oneline│ View compact history │
│ git branch │ List branches │
│ git branch <name>│ Create new branch │
│ git switch <name>│ Switch to branch │
│ git switch -c │ Create and switch to new branch │
│ git merge │ Merge branch into current branch │
│ git diff │ See unstaged changes │
│ git diff --staged│ See staged changes │
│ git clone <url> │ Copy repository from remote │
│ git pull │ Get latest changes from remote │
│ git push │ Send commits to remote │
└─────────────────┴──────────────────────────────────────────┘
Common Beginner Mistakes and Solutions
1. Forgot to Stage Files Before Commit
❌ Mistake:
# Edit file
echo "new content" >> index.html
# Try to commit without staging
git commit -m "Update index"
Result: Nothing happens!
✅ Solution:
git add index.html
git commit -m "Update index"
2. Committing to Wrong Branch
❌ Mistake:
# You're on main but meant to work on feature branch
git commit -m "Add new feature"
✅ Solution (if you haven't pushed):
# Undo last commit but keep changes
git reset --soft HEAD~1
# Switch to correct branch
git switch feature-branch
# Commit again
git commit -m "Add new feature"
3. Unclear Commit Messages
❌ Bad:
git commit -m "fix"
git commit -m "update"
git commit -m "changes"
✅ Good:
git commit -m "Fix login button alignment issue"
git commit -m "Update user profile API endpoint"
git commit -m "Add validation for email input"
Practical Tips for Beginners
1. Commit Often, Push Less Frequently
✅ Good practice:
Make many small commits locally, then push when feature is complete
Commits: "Add button" → "Style button" → "Add click handler"
↓
Push once
2. Write Meaningful Commit Messages
Follow this format:
Type: Brief description
- What changed
- Why it changed (if not obvious)
Example:
Fix: Resolve login redirect loop
- Changed redirect logic to check authentication state
- Added session validation before redirect
3. Check Status Before Committing
Always run git status to see what you're about to commit:
git status
git add .
git status # Check again!
git commit -m "message"
4. Use .gitignore for Files You Don't Want to Track
Create a .gitignore file to exclude files:
# .gitignore
node_modules/
.env
*.log
.DS_Store
Conclusion
You've learned:
✅ What Git is and why it's essential
✅ Core concepts: repository, commit, branch, staging area
✅ Essential commands: init, add, commit, branch, merge, etc.
✅ A complete developer workflow from scratch
✅ Common mistakes and how to avoid them
Happy coding! 🚀
Useful Resources:
Official Git documentation: https://git-scm.com/doc
Interactive Git tutorial: https://learngitbranching.js.org
Git command cheat sheet: https://education.github.com/git-cheat-sheet-education.pdf