Git Basics (init, add, commit)

Difficulty: Beginner

Question

Walk me through the basic Git workflow. What are the three areas in Git, and how do files move between them?

Answer

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.

Code examples

Initialize and First Commit

# 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.

Selective Staging

# 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.

Commit Best Practices

# 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.

Key points

Concepts covered

git init, git add, git commit, Staging Area, Working Directory