Skip to content

Git Fundamentals

Git is a distributed version control system. Every developer has a full copy of the repository history, and changes are tracked as a series of snapshots (commits).

TermDescription
RepositoryThe .git directory that stores all history and metadata
Working treeThe files you see and edit
Index / Staging areaChanges prepared for the next commit
CommitA snapshot of staged changes with metadata (author, timestamp, message)
BranchA lightweight pointer to a commit
HEADA pointer to the current branch (or commit in detached HEAD state)
RemoteA version of the repository hosted elsewhere (GitHub, GitLab, etc.)
Terminal window
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global core.editor "code --wait" # VS Code as editor
git config --global init.defaultBranch main
# View all config
git config --list
Terminal window
# New repo
git init
git init my-project # creates directory
# Clone existing repo
git clone https://github.com/user/repo.git
git clone https://github.com/user/repo.git my-folder # custom directory name

Files move through three states:

Untracked / Modified → Staged → Committed
git add ↑ git commit ↑
Terminal window
# Check current state
git status
git status -s # short format
# Stage specific files
git add file.txt
git add src/ # entire directory
git add . # everything in working directory
# Unstage
git restore --staged file.txt
# Commit staged changes
git commit -m "Add user authentication"
# Stage and commit tracked files in one step
git commit -am "Fix typo in README"
Terminal window
git log
git log --oneline # compact view
git log --oneline --graph # with branch graph
git log --oneline -10 # last 10 commits
git log --author="Alice"
git log --since="2 weeks ago"
git log -- path/to/file # commits affecting a specific file
git show abc1234 # show a specific commit
Terminal window
# Create and switch
git branch feature/login
git switch feature/login
git switch -c feature/login # create + switch in one step
# List branches
git branch # local
git branch -r # remote
git branch -a # all
# Delete
git branch -d feature/login # safe delete (warns if unmerged)
git branch -D feature/login # force delete
# Rename
git branch -m old-name new-name
Terminal window
# Merge feature branch into main
git switch main
git merge feature/login
# Merge with a merge commit (no fast-forward)
git merge --no-ff feature/login
# Abort a merge in progress
git merge --abort
Terminal window
# List remotes
git remote -v
# Add a remote
git remote add origin https://github.com/user/repo.git
# Push
git push origin main
git push -u origin main # set upstream (then use just `git push`)
git push --all # push all branches
# Pull (fetch + merge)
git pull
# Fetch (download without merging)
git fetch origin
# Delete remote branch
git push origin --delete feature/old-branch
Terminal window
# Changes not yet staged
git diff
# Staged changes (about to be committed)
git diff --staged
git diff --cached # same thing
# Between two commits
git diff abc1234 def5678
# Between branches
git diff main feature/new
# Dependencies
node_modules/
.venv/
# Build output
dist/
build/
*.pyc
# Secrets
.env
.env.local
*.pem
secrets.json
# IDE
.vscode/
.idea/
*.swp

Generate recommended .gitignore files at gitignore.io.