Git Cheatsheet

Git is a version control system that tracks changes to files over time. You can review history, undo mistakes, and work on separate features in parallel without breaking the main codebase. It is the standard tool for every development team.

Git vs GitHub

Git is the tool that runs on your computer. GitHub is a website that hosts your Git repositories online. You use Git locally and push to GitHub to share or back up your work. GitLab and Bitbucket are alternatives to GitHub.

Installing Git

macOS: Git is often pre-installed. Check first:

git --version

If not installed, install via Homebrew:

brew install git

Or download from https://git-scm.com/

Windows: Download Git for Windows from https://git-scm.com/ (includes Git Bash terminal).

Linux (Debian/Ubuntu):

sudo apt update && sudo apt install git

First-time setup

Before you can commit, tell Git your name and email. Use the same email as your GitHub account.

git config --global user.name "Your Name"
git config --global user.email "yourname@example.com"

Verify your config:

git config --get user.name
git config --get user.email

Set your default branch name to main (matches GitHub’s default):

git config --global init.defaultBranch main

SSH key setup (for GitHub)

SSH keys let you push to GitHub without entering your password every time.

Check if you already have a key:

ls ~/.ssh/id_ed25519.pub

If not, generate one (Ed25519 is the recommended key type):

ssh-keygen -t ed25519 -C "yourname@example.com"

Press Enter to accept the default file location. Set a passphrase if you want extra security (recommended).

Copy your public key:

cat ~/.ssh/id_ed25519.pub

Go to GitHub > Settings > SSH and GPG keys > New SSH key, paste the key, and save. Test the connection:

ssh -T git@github.com

How Git tracks changes

Every Git project has three areas:

  • Working directory: the files you edit on disk
  • Staging area (index): changes you have marked as ready to commit
  • Repository: the permanent history of commits

The flow is: edit a file, stage it with git add, then commit it with git commit.

Starting a project

Initialise a new repository in the current folder:

git init

This creates a hidden .git folder. Do not delete it.

Clone an existing repository from GitHub:

git clone https://github.com/username/repository.git

This downloads the project and sets up origin as the remote automatically.

Daily workflow

Check what has changed:

git status

Stage changes:

git add filename.js        # stage one file
git add .                  # stage everything in the current directory
git add -A                 # stage all changes including deletions

Commit staged changes:

git commit -m "Add login form validation"

Write commit messages in the present tense. Keep them under 72 characters. Describe what the change does, not what you did.

View commit history:

git log            # full history
git log --oneline  # one line per commit, easier to scan

Viewing changes

Differences not yet staged:

git diff

Differences staged but not committed:

git diff --staged

Differences between two commits:

git diff abc1234 def5678

Branching

Branches let you work on a feature without touching the main codebase.

List branches:

git branch

Create a branch:

git branch feature-login

Switch to a branch (modern syntax):

git switch feature-login

Create and switch in one step:

git switch -c feature-login

Note: older tutorials use git checkout branch-name. Both work, but git switch is clearer.

Commit on a branch the same as normal: git add, then git commit.

Merge a branch into main:

git switch main
git merge feature-login

Delete a branch after merging:

git branch -d feature-login

Warning: git branch -D feature-login (capital D) force-deletes a branch even if it has never been merged. Commits on that branch will be lost. Only use -D if you are certain you do not need those changes.

Working with remotes

See your remotes:

git remote -v

Add a remote (if you used git init instead of clone):

git remote add origin https://github.com/username/repo.git

Push your branch to the remote:

git push origin main          # push main branch
git push -u origin feature-x  # push and set upstream tracking

After setting -u once, you can run git push on its own for that branch.

Pull changes from the remote:

git pull

git pull fetches new commits from the remote and merges them into your current branch. Run this before you start work each day.

Fetch without merging (useful when you want to inspect before applying):

git fetch
git merge origin/main

Undoing changes safely

Discard unstaged changes to a file:

git restore filename.js

This resets the file to the last committed state. Note: older tutorials use git checkout -- filename. Both work.

Unstage a file (keeps your changes, just removes it from the staging area):

git restore --staged filename.js

Note: older tutorials use git reset HEAD filename. Both work.

Undo a commit safely:

git revert abc1234

git revert creates a new commit that reverses a previous one. It does not rewrite history, so it is safe to use on shared branches.

Stash work in progress:

git stash          # save current changes and clean the working directory
git stash pop      # restore the stashed changes
git stash list     # see all stashes

Use git stash when you need to switch branches but are not ready to commit.

Warning: git reset --hard and git reset <commit> rewrite history and can permanently lose commits. Do not use these on shared branches. If you need to undo a pushed commit, use git revert instead.

.gitignore

A .gitignore file tells Git which files to ignore. Create one in your project root.

# Dependencies
node_modules/

# Environment variables (contains secrets, never commit)
.env

# Build output
dist/
build/

# OS files
.DS_Store
Thumbs.db

# Logs
*.log

Any file or folder matching these patterns will not be tracked by Git.

If you accidentally committed a file before adding it to .gitignore, remove it from tracking without deleting it from disk:

git rm --cached filename
git commit -m "Stop tracking filename"

See the Node.js project structure page for a Node-specific .gitignore.

Resolving merge conflicts

A merge conflict happens when two branches have changed the same part of the same file and Git cannot automatically decide which version to keep.

When a conflict occurs, git merge stops and marks the affected files:

Auto-merging index.js
CONFLICT (content): Merge conflict in index.js
Automatic merge failed; fix conflicts and then commit the result.

Open the conflicting file. Git marks the conflict like this:

<<<<<<< HEAD
const greeting = 'Hello';
=======
const greeting = 'Hi there';
>>>>>>> feature-greeting
  • Everything between <<<<<<< HEAD and ======= is your current branch’s version.
  • Everything between ======= and >>>>>>> is the incoming branch’s version.

Edit the file to keep what you want, then delete the conflict markers:

const greeting = 'Hello';

Stage and commit the resolved file:

git add index.js
git commit -m "Resolve merge conflict in index.js"

To abort the merge and go back to where you were:

git merge --abort

Beginner workflow: full loop

This is the typical day-to-day workflow for a solo developer:

# Get the latest changes from the remote
git pull

# Create a branch for your feature
git switch -c feature-dark-mode

# Edit your files, then check what changed
git status

# Stage the changes
git add .

# Commit with a clear message
git commit -m "Add dark mode toggle to navbar"

# Push your branch to the remote
git push origin feature-dark-mode

# On GitHub, open a pull request to merge into main.
# After the PR is merged, switch back to main and pull.
git switch main
git pull

Quick reference

CommandWhat it does
git initCreate a new repository
git clone <url>Copy a remote repository locally
git statusShow what has changed
git add .Stage all changes
git commit -m "msg"Commit with a message
git log --onelineShow compact commit history
git diffShow unstaged changes
git branchList branches
git switch <name>Switch to a branch
git switch -c <name>Create and switch to a branch
git merge <name>Merge a branch into the current branch
git pullFetch and merge from remote
git push origin <name>Push a branch to remote
git restore <file>Discard unstaged changes to a file
git restore --staged <file>Unstage a file
git revert <sha>Safely undo a commit
git stashSave work in progress temporarily
git stash popRestore stashed work