Git Commands Every Developer Should Know

Git Commands Every Developer Should Know


Git is the backbone of modern software development. Yet many developers only scratch the surface, sticking to add, commit, and push. Let’s change that. Here are the Git commands and workflows that will make you faster, safer, and more confident.

The Basics, Done Right

Write Better Commit Messages

Before we dive into commands, let’s talk commits. Good commit messages are a gift to your future self and teammates.

# ❌ Vague and unhelpful
git commit -m "fixed stuff"

# ✅ Clear and descriptive
git commit -m "fix: resolve null pointer exception in user authentication"

Consider using Conventional Commits: feat:, fix:, docs:, refactor:, test:, etc.

Stage Interactively

Don’t just git add . everything. Use interactive staging to craft clean, logical commits:

# Stage specific hunks within a file
git add -p

# This prompts you for each change:
# y - stage this hunk
# n - skip this hunk
# s - split into smaller hunks
# e - manually edit the hunk

Undoing Mistakes

We all make mistakes. Git makes it easy to recover.

Undo Your Last Commit (Keep Changes)

# Undo commit but keep changes staged
git reset --soft HEAD~1

# Undo commit and unstage changes (but keep files)
git reset HEAD~1

# ⚠️ Undo commit and discard all changes (dangerous!)
git reset --hard HEAD~1

Fix Your Last Commit Message

git commit --amend -m "New, better commit message"

Accidentally Staged a File?

# Unstage a specific file
git restore --staged filename.js

# Unstage everything
git restore --staged .

Discard Local Changes

# Discard changes in a specific file
git restore filename.js

# Discard all local changes (careful!)
git restore .

Branching Like a Pro

Create and Switch in One Command

# Old way (two commands)
git branch feature/new-login
git checkout feature/new-login

# New way (one command)
git switch -c feature/new-login

See All Branches (Local and Remote)

git branch -a

Delete Branches Safely

# Delete local branch (only if merged)
git branch -d feature/old-branch

# Force delete local branch
git branch -D feature/old-branch

# Delete remote branch
git push origin --delete feature/old-branch

Clean Up Stale Remote Branches

# Remove references to deleted remote branches
git fetch --prune

The Power of Stash

Stash lets you temporarily shelve changes without committing.

# Stash current changes
git stash

# Stash with a descriptive message
git stash push -m "WIP: halfway through refactoring auth"

# List all stashes
git stash list

# Apply most recent stash (keeps it in stash list)
git stash apply

# Apply and remove from stash list
git stash pop

# Apply a specific stash
git stash apply stash@{2}

# Drop a specific stash
git stash drop stash@{0}

Rebase: Cleaner History

Rebasing rewrites history to create a linear commit timeline. Use it to keep your feature branch up to date.

# Rebase your feature branch onto main
git checkout feature/my-feature
git rebase main

# Interactive rebase to squash/edit last 3 commits
git rebase -i HEAD~3

Interactive Rebase Commands

When you run git rebase -i, you’ll see options like:

  • pick — keep the commit as-is
  • squash — combine with previous commit
  • reword — change the commit message
  • edit — pause to amend the commit
  • drop — remove the commit entirely

Pro tip: Squash your WIP commits before merging a PR:

# Squash all commits on your branch into one
git rebase -i main
# Then change all but the first "pick" to "squash"

Finding Things

Search Commit History

# Find commits containing a specific message
git log --grep="authentication"

# Find commits that changed a specific file
git log -- path/to/file.js

# Find who changed a specific line
git blame path/to/file.js

Find When a Bug Was Introduced

# Binary search through commits
git bisect start
git bisect bad              # Current commit is broken
git bisect good abc123      # This old commit was working

# Git will checkout commits for you to test
# After testing each:
git bisect good  # or
git bisect bad

# When done:
git bisect reset

Working with Remotes

View Remote URLs

git remote -v

Add Multiple Remotes

# Add upstream for a forked repo
git remote add upstream https://github.com/original/repo.git

# Fetch from upstream
git fetch upstream

# Merge upstream changes into your branch
git merge upstream/main

Push a New Branch

# Push and set upstream tracking
git push -u origin feature/my-feature

Cherry-Pick: Selective Commits

Apply specific commits from another branch:

# Apply a single commit to current branch
git cherry-pick abc123

# Apply multiple commits
git cherry-pick abc123 def456

# Cherry-pick without committing (just stage changes)
git cherry-pick --no-commit abc123

Useful Aliases

Add these to your ~/.gitconfig:

[alias]
  co = checkout
  br = branch
  ci = commit
  st = status
  unstage = reset HEAD --
  last = log -1 HEAD
  visual = log --oneline --graph --decorate --all
  amend = commit --amend --no-edit

Now you can use git visual for a beautiful branch graph or git amend to quickly add to your last commit.

The Golden Rules

  1. Commit often, push regularly — Small commits are easier to review and revert
  2. Never rebase shared branches — Only rebase your own feature branches
  3. Write meaningful messages — Your future self will thank you
  4. Use branches liberally — They’re cheap and keep work isolated
  5. Review before pushinggit diff --staged is your friend

Git has a learning curve, but mastering it pays dividends every day. What’s your favorite Git trick? Drop it in the comments!