Difficulty: Beginner
Walk me through the basic Git workflow. What are the three areas in Git, and how do files move between them?
Git has three main areas where files exist:
1. Working Directory: Your actual project files on disk. When you edit a file, the change lives here. 2. Staging Area (Index): A holding zone where you prepare your next commit. You choose exactly which changes to include. 3. Repository (.git): The permanent history. Once committed, snapshots are stored here.
The flow is: Edit files (working dir) → git add (staging) → git commit (repository). This three-stage design is powerful because it lets you craft precise commits. You can edit 10 files but only stage and commit 3 of them, keeping your commits focused and reviewable.
Understanding this model is foundational. Every Git command moves data between these three areas. git status shows you where everything currently sits.
# Create a new repository
mkdir my-project && cd my-project
git init
# Initialized empty Git repository in .git/
# Check status - nothing tracked yet
git status
# On branch main
# No commits yet
# nothing to commit
# Create files
echo '# My Project' > README.md
echo 'node_modules/' > .gitignore
# Stage specific files
git add README.md .gitignore
# Check what's staged
git status
# Changes to be committed:
# new file: .gitignore
# new file: README.md
# Commit with a message
git commit -m "Initial commit: add README and gitignore"
# [main (root-commit) a1b2c3d] Initial commit: add README and gitignore
# 2 files changed, 2 insertions(+)
git init creates the .git directory. git add moves files from working directory to staging. git commit takes a snapshot of everything staged.
# Edit multiple files
echo 'console.log("hello")' > index.js
echo 'body { margin: 0 }' > styles.css
echo 'Updated docs' >> README.md
# Stage only specific files
git add index.js
git status
# Changes to be committed:
# new file: index.js
# Changes not staged for commit:
# modified: README.md
# Untracked files:
# styles.css
# Stage parts of a file (patch mode)
git add -p README.md
# Shows each hunk, you choose y/n/s(split)
# Unstage a file (keep changes in working dir)
git restore --staged index.js
# Or older syntax: git reset HEAD index.js
# Stage everything (use carefully)
git add -A # stages all changes including deletions
git add . # stages new + modified in current dir
Selective staging is a key skill. git add -p lets you stage individual chunks within a file, enabling very precise commits.
# Good commit messages follow conventions:
# <type>: <subject>
# Types: feat, fix, docs, style, refactor, test, chore
# Single-line commit
git commit -m "feat: add user registration endpoint"
# Multi-line commit (opens editor)
git commit
# In editor:
# feat: add user registration endpoint
#
# - Added POST /api/auth/register route
# - Password hashing with bcrypt
# - Email uniqueness validation
# - Returns JWT token on success
# Amend the last commit (before pushing!)
git commit --amend -m "feat: add user registration with email validation"
# See commit details
git show HEAD
# Shows the diff of the last commit
# See compact log
git log --oneline -5
# a1b2c3d feat: add user registration endpoint
# e4f5g6h fix: resolve CORS issue
# i7j8k9l chore: update dependencies
Good commit messages are imperative ('Add feature' not 'Added feature'). The Conventional Commits format (feat/fix/docs) makes changelogs and versioning automatic.
git init, git add, git commit, Staging Area, Working Directory