DEV Community

Alex Chen
Alex Chen

Posted on

Git Advanced: The Commands I Wish I Knew Earlier (2026)

Git Advanced: The Commands I Wish I Knew Earlier (2026)

Beyond add, commit, push. These are the Git commands that actually save time.

The Basics (Quick Refresher)

git status          # What changed?
git diff             # What exactly changed?
git log --oneline   # Recent commits
git add -A           # Stage everything
git commit -m "msg"  # Commit staged changes
git push origin main # Send to remote
Enter fullscreen mode Exit fullscreen mode

You know these. Let's go further.

Undo Everything (Safely)

# Unstage a file (keep changes)
git reset HEAD path/to/file

# Discard all unstaged changes in a file
git checkout -- path/to/file
# Or newer syntax:
git restore path/to/file

# Discard ALL unstaged changes
git checkout -- .
git restore .

# Uncommit (keep changes, remove commit)
git reset --soft HEAD~1    # Changes stay staged
git reset HEAD~1           # Changes stay unstaged
git reset --hard HEAD~1    # Changes GONE forever ⚠️

# Amend last commit (fix message or add forgotten file)
git commit --amend -m "Better message"
git add forgotten-file.txt
git commit --amend         # Add file to previous commit
Enter fullscreen mode Exit fullscreen mode

Interactive Rebase: Clean Up History

# Edit/reorder/squash last 5 commits
git rebase -i HEAD~5

# Opens editor with:
pick abc1234 First commit
pick def5678 Second commit
pick ghi9012 Third commit
pick jkl3456 Fourth commit
pick mno7890 Fifth commit

# Change 'pick' to:
# reword  = edit commit message
# edit    = pause to amend files
# squash  = merge into previous commit
# fixup   = merge into previous (discard this message)
# drop    = remove commit entirely
# exec    = run shell command

# Example: Squash the last 2 commits into one
pick abc1234 First commit
squash def5678 Second commit
# → Creates single commit with combined changes
Enter fullscreen mode Exit fullscreen mode

Stashing: Save Work Without Committing

# Save current work temporarily
git stash
git stash push -m "WIP: feature X"

# List all stashes
git stash list
# stash@{0}: On main: WIP: feature X
# stash@{1}: On main: bugfix attempt

# Restore most recent stash
git stash pop      # Apply + remove from list
git stash apply    # Apply + keep in list

# Restore specific stash
git stash apply stash@{1}

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

# Clear all stashes
git stash clear

# Stash only some files (not everything)
git stash push -m "partial" src/utils.js src/config.js

# Stash with untracked files included
git stash push -u -m "include new files"
Enter fullscreen mode Exit fullscreen mode

Searching Through History

# Search commit messages
git log --grep="bug fix" --oneline
git log --grep="auth" --since="2026-01-01"

# Search code content across all history
git log -S "functionName" --oneline     # Added/removed this string
git log -G "pattern" --oneline          # Changed matching this regex
git log -p -S "TODO"                    # Show actual diffs too

# Find which commit introduced a bug
git bisect start
git bisect bad                          # Current version has bug
git bisect good v1.0.0                  # This version was fine
# Git will check out middle commit → you test → mark good/bad
# Repeat until it finds the exact bad commit
git bisect reset                        # When done

# Search current working tree
git grep "search term"                  # In tracked files
git grep "search term" $(git rev-list --all)  # Across ALL history!
Enter fullscreen mode Exit fullscreen mode

Branching Strategies That Work

Feature Branch Workflow

# Start a new feature
git checkout -b feature/user-auth
# Or:
git switch -c feature/user-auth

# Make commits...
git add -A && git commit -m "Add login page"

# Update your branch with latest main
git fetch origin
git rebase origin/main        # Cleaner than merge for PRs

# Push branch (first time needs -u)
git push -u origin feature/user-auth

# After PR is merged, clean up
git branch -d feature/user-auth              # Delete local
git push origin --delete feature/user-auth   # Delete remote
Enter fullscreen mode Exit fullscreen mode

Quick Branch Management

# See all branches (local + remote)
git branch -a

# Rename current branch
git branch -m old-name new-name

# Rename remote branch (after local rename)
git push origin :old-name new-name

# Switch to previous branch
git checkout -
# Or: git switch -

# Compare branches
git log main..feature-branch --oneline    # Commits in feature but not main
git diff main...feature-branch            # Diff between branch tips

# Merge vs Rebase summary:
# git merge feature   → Creates merge commit, preserves exact history
# git rebase feature  → Linear history, rewrites commits (cleaner for PRs)
Enter fullscreen mode Exit fullscreen mode

Dealing with Remote Changes

# Fetch all remotes (doesn't merge)
git fetch --all

# Pull = fetch + merge
git pull origin main

# Pull with rebase (avoids extra merge commits)
git pull --rebase origin main

# Force push (⚠️ dangerous on shared branches!)
git push --force-with-lease origin feature-branch
# Safer than --force: checks if remote changed first

# Remove remote tracking branch that was deleted
git prune
git fetch --prune                         # Fetch + cleanup stale refs
Enter fullscreen mode Exit fullscreen mode

Cherry-Picking: Grab Specific Commits

# Apply one commit from another branch
git cherry-pick abc1234

# Apply multiple commits
git cherry-pick abc1234 def5678 ghi9012

# Cherry-pick without committing (edit first)
git cherry-pick -n abc1234
# Make changes, then:
git commit -m "Modified cherry-pick"

# Cherry-pick from another repo (as patch)
git format-patch -1 abc1234 --stdout > /tmp/patch.git
git am < /tmp/patch.git
Enter fullscreen mode Exit fullscreen mode

Fixing Mistakes in Committed Code

# Forgot to include a file in last commit?
git add forgotten-file.js
git commit --amend --no-edit

# Need to change an older commit? Use interactive rebase:
git rebase -i HEAD~5
# Change 'pick' to 'edit' on the target commit
# Make your changes
git add fixed-file.js
git rebase --continue

# Split a commit into two:
git rebase -i HEAD~3
# Change 'pick' to 'edit' on target commit
git reset HEAD~1                # Uncommit while keeping changes
git add file-a.js               # Stage part of changes
git commit -m "Part A: file A"
git add file-b.js               # Stage rest
git commit -m "Part B: file B"
git rebase --continue
Enter fullscreen mode Exit fullscreen mode

Understanding .gitignore

# Patterns
node_modules/                   # Directory
*.log                           # All .log files
!.important.log                 # Except this one
build/                          # Build output
.env                            # Secrets (NEVER commit!)
.DS_Store                       # macOS junk
.vscode/                        # Editor config (optional)

# Global ignore (for all repos)
git config --global core.excludesfile ~/.gitignore_global

# Debug what's being ignored
git check-ignore -v node_modules/debug.log
git status --ignored            # Show ignored files too

# Track a file that's already .gitignored
git add -f important.log        # Force add (-f overrides ignore rules)

# Stop tracking a file (but keep locally)
git rm --cached large-file.dat
# Then add to .gitignore
Enter fullscreen mode Exit fullscreen mode

Useful Aliases

# Save typing with aliases
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.lg "log --graph --oneline --decorate -20"
git config --global alias.unstage "reset HEAD --"
git config --global alias.last "log -1 --stat"
git config --global alias.amend "commit --amend --no-edit"
git config --global alias.cleanup "!git branch --merged | grep -v '\\*\\|main\\|develop' | xargs git branch -d"
git config --global alias.discard "checkout --"

# Now use:
git co feature-branch       # = git checkout
git lg                      # Beautiful graph log
git cleanup                 # Delete merged branches
git discard filename        # Discard changes to file
Enter fullscreen mode Exit fullscreen mode

Quick Reference Card

Task Command
Undo last commit (keep files) git reset --soft HEAD~1
Undo last commit (lose files) git reset --hard HEAD~1
Amend last commit git commit --amend
Save work temporarily git stash / git stash pop
Edit recent commits git rebase -i HEAD~N
Find commit that added text git log -S "text"
Compare branches git diff main...feature
Clean merged branches `git branch --merged \
Safe force push {% raw %}git push --force-with-lease
Grab commit from other branch git cherry-pick <sha>
Bisect to find bug commit git bisect start/good/bad/reset

Which Git command saved you the most time?

Follow @armorbreak for more practical developer guides.

Top comments (0)