Skip to content

Git Fundamentals

Git’s Mental Model

Before diving into commands, it is essential to understand the three areas where your files live in a Git project. This mental model is the foundation for everything else.

┌──────────────────┐ git add ┌──────────────────┐ git commit ┌──────────────────┐
│ │ ──────────────► │ │ ──────────────► │ │
│ Working Directory│ │ Staging Area │ │ Repository │
│ │ ◄────────────── │ (Index) │ │ (.git) │
│ │ git restore │ │ │ │
└──────────────────┘ └──────────────────┘ └──────────────────┘
Your files Files ready for Permanent snapshots
on disk the next commit (commit history)
  • Working Directory — The actual files on your filesystem. This is where you edit, create, and delete files.
  • Staging Area (Index) — A preparation zone where you assemble changes before committing. You choose exactly which changes go into the next commit.
  • Repository (.git directory) — The database of all commits, branches, and metadata. Once a change is committed here, it is part of the permanent history.

This three-stage architecture gives you fine-grained control. You can modify ten files but commit only three of them, keeping the rest for a separate commit.

Interactive Git Playground

Practice Git commands interactively. Create branches, make commits, merge, and rebase — see the commit graph update in real time.

Git Graph Visualizer

on main
Scenarios
Command
Supported: git commit -m "msg" | git branch name | git checkout name | git merge name | git rebase name
Quick Actions
Commit Graph
mainb390347b390347 — Initial commitmainHEAD
History Log
No commands executed yet. Try typing a git command or use the quick actions above.
main (HEAD)

Setting Up Git

Before using Git, configure your identity. This information is attached to every commit you make.

Terminal window
# Set your name and email (used in commit metadata)
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
# Optional: set your preferred text editor
git config --global core.editor "code --wait"
# Optional: set default branch name to 'main'
git config --global init.defaultBranch main
# Verify your configuration
git config --list

Essential Git Commands

Initializing and Cloning

Create a new Git repository in the current directory.

Terminal window
# Initialize a new repository
mkdir my-project
cd my-project
git init

This creates a hidden .git directory that stores all version control data. Your project files remain untouched.

Inspecting State

Show the current state of your working directory and staging area.

Terminal window
git status

Example output:

On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: src/app.js
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
modified: src/utils.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
src/newfile.js

Use git status -s for a compact summary.

Staging and Committing

Move changes from the working directory to the staging area.

Terminal window
# Stage a specific file
git add src/app.js
# Stage multiple specific files
git add src/app.js src/utils.js
# Stage all changes in a directory
git add src/
# Stage all changes in the entire project
git add .
# Stage parts of a file interactively
git add -p src/app.js

The staging area lets you craft commits precisely. Stage only the changes that belong together logically.

Branching and Merging

Branches are one of Git’s most powerful features. They allow you to diverge from the main line of development and work in isolation.

┌─── C4 ─── C5 (feature)
/
C1 ─── C2 ─── C3 (main)

Manage branches.

Terminal window
# List all local branches
git branch
# List all branches (local and remote)
git branch -a
# Create a new branch
git branch feature-login
# Delete a branch (safe -- only if merged)
git branch -d feature-login
# Rename current branch
git branch -m new-name

Handling Merge Conflicts

When Git cannot automatically merge changes, it produces a conflict. The conflicted file will contain markers showing both versions:

<<<<<<< HEAD
function greet(name) {
return `Hello, ${name}!`;
}
=======
function greet(name) {
return `Hi there, ${name}!`;
}
>>>>>>> feature-branch

Steps to resolve:

  1. Open the conflicted file and decide which changes to keep (or combine both).
  2. Remove the conflict markers (<<<<<<<, =======, >>>>>>>).
  3. Stage the resolved file: git add src/app.js
  4. Complete the merge: git commit

Undoing Changes

Discard changes in the working directory or unstage files.

Terminal window
# Discard changes in a file (revert to last commit)
git restore src/app.js
# Unstage a file (keep changes in working directory)
git restore --staged src/app.js

Working with Remotes

Manage connections to remote repositories.

Terminal window
# List remotes
git remote -v
# Add a remote
git remote add origin https://github.com/user/repo.git
# Change a remote URL
git remote set-url origin https://github.com/user/new-repo.git
# Remove a remote
git remote remove origin

Common Workflows

Solo Developer Workflow

Terminal window
# 1. Make changes to files
# 2. Review what changed
git status
git diff
# 3. Stage and commit
git add .
git commit -m "Implement feature X"
# 4. Push to remote
git push origin main

Feature Branch Workflow

Terminal window
# 1. Create a feature branch from main
git checkout -b feature-search
# 2. Work on the feature (edit, stage, commit -- repeat)
git add src/search.js
git commit -m "Add search input component"
git add src/search.js src/api.js
git commit -m "Connect search to API"
# 3. Push the feature branch to remote
git push -u origin feature-search
# 4. Open a pull request (on GitHub/GitLab)
# 5. After approval, merge into main
git checkout main
git pull origin main
git merge feature-search
# 6. Clean up
git branch -d feature-search
git push origin --delete feature-search

Quick Reference

CommandPurpose
git initInitialize a new repository
git clone <url>Copy a remote repository locally
git statusShow working directory state
git add <file>Stage changes for commit
git commit -m "msg"Create a commit from staged changes
git log --onelineView compact commit history
git diffShow unstaged changes
git branch <name>Create a new branch
git checkout <branch>Switch to a branch
git merge <branch>Merge a branch into current branch
git rebase <branch>Reapply commits onto another branch
git stashTemporarily save uncommitted changes
git pushUpload commits to remote
git pullDownload and merge remote changes
git fetchDownload remote changes without merging
git resetMove branch pointer / unstage changes
git restoreDiscard working directory changes

Next Steps

Now that you understand the core Git commands, explore how teams organize their branches and review each other’s code: