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 commit, push, and pull. These are the commands that make you significantly more productive.

Rewriting History (Safe & Useful)

# Amend the last commit (fix typo, add forgotten file)
git commit --amend -m "Better message"
# or: git add forgotten-file && git commit --amend --no-edit

# Interactive rebase — the most powerful Git command
git rebase -i HEAD~3
# Opens editor with last 3 commits:
#
# pick abc1234 Initial implementation
# pick def5678 Add feature X
# pick ghi9012 Fix bug in feature X
#
# Available commands:
#   p, pick = use commit as-is
#   r, reword = change message only
#   e, edit = stop here to amend/split
#   s, squash = merge into previous commit
#   f, fixup = merge into previous (discard message)
#   d, drop = remove commit entirely

# Example: Squash "Fix bug" into "Add feature X"
# Change line to: s ghi9012
# Result: One clean commit with both changes

# Reorder commits (just move lines in the editor)
# Split a commit (mark as 'e', then reset HEAD~1, create multiple commits)

# ⚠️ Only rebase local history! Never rebase pushed/shared commits.
Enter fullscreen mode Exit fullscreen mode

Searching Through History

# Search commit messages
git log --grep="bug" --oneline          # Messages containing "bug"
git log --grep="auth" --since="2026-01-01" --oneline  # Time-bounded

# Search code changes (find which commit changed something)
git log -S "functionName" --oneline      # When was this text added/removed?
git log -G "pattern" --oneline           # Regex search through diffs
git log -p -S "API_KEY"                  # Show actual diff of when it appeared

# Search file history
git log --follow -- filename             # Track across renames
git show abc1234:path/to/file            # View file at specific commit
git diff main..feature --stat            # What files changed between branches?

# Who wrote this line? (blame)
git blame filename                       # Line-by-line authorship
git blame -L 10,20 filename             # Lines 10-20 only
git blame -e filename                   # Show email addresses

# Find commits by author/time
git log --author="Alice" --oneline       # Commits by specific person
git log --after="2026-05-01" --before="2026-06-01" --oneline  # Date range
Enter fullscreen mode Exit fullscreen mode

Stashing Like a Pro

# Basic stash
git stash                              # Save working directory changes
git stash save "WIP: auth feature"     # With descriptive message
git stash list                         # List all stashes
git stash pop                          # Apply and remove most recent
git stash apply                        # Apply but keep in list
git stash drop                          # Remove without applying
git stash clear                         # Remove ALL stashes

# Stash specifics (not everything)
git stash -m "temp" -- filename        # Stash only one file
git stash -u                            # Include untracked files too
git stash -k                            # Keep changes in working dir AND stash

# Work with multiple stashes
git stash show stash@{2}               # Preview what's in stash #2
git stash apply stash@{1}              # Apply specific stash
git stash branch new-branch stash@{0}  # Create branch from stash

# Practical use case: Emergency context switch
# You're mid-feature, boss needs a hotfix NOW
git stash -m "WIP: feature 80% done"
git checkout -b hotfix/critical-bug
# ... fix, commit, push ...
git checkout feature-branch
git stash pop                           # Back where you left off!
Enter fullscreen mode Exit fullscreen mode

Recovering from Mistakes

# I committed to the wrong branch!
git reset --soft HEAD~1                # Undo commit, keep changes staged
git checkout correct-branch
git commit                             # Commit on right branch

# I pushed to the wrong branch!
git reset --soft HEAD~1                # Undo the bad commit
git checkout correct-branch
git commit
git push origin correct-branch         # Push to correct branch
git push origin --force wrong-branch   # Remove from wrong branch (⚠️ destructive!)

# I need to undo a pushed commit (clean up history)
git revert abc1234                      # Creates NEW commit that undoes the change
# Safer than force-push! Preserves history.

# I deleted a file I need back!
git checkout -- filename              # Restore from last commit
git checkout abc1234 -- filename       # Restore from specific commit
git reflog                              # Find lost commits
git checkout abc1234                    # Recover any past state

# reflog is your safety net!
git reflog                             # Shows EVERY state your HEAD has been
# abc1234 HEAD@{0}: commit: Add feature
# def5678 HEAD@{1}: commit: Fix typo
# ghi9012 HEAD@{2}: reset: moving to HEAD~1
git checkout -b recovery ghi9012       # Restore "lost" commit
Enter fullscreen mode Exit fullscreen mode

Branching Strategies

# Create branch from specific point
git checkout -b feature-x abc1234     # Branch from that commit

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

# Merge vs Rebase vs Squash Merge
git merge feature                      # Creates merge commit (preserves history)
git rebase main                        # Linear history (rewrites feature's commits)
git merge --squash feature            # One commit on main (clean but loses detail)

# Cherry-pick specific commits
git cherry-pick abc1234               # Apply one commit from another branch
git cherry-pick abc1234 def5678       # Apply multiple
git cherry-pick --no-commit abc1234   # To staging area (edit before committing)

# Clean up merged branches
git branch --merged | grep -v 'main' | xargs git branch -d  # Delete merged branches
git branch -d feature-x               # Delete merged branch safely
git branch -D feature-y               # Force delete unmerged branch

# Rename branch (local + remote)
git branch -m old-name new-name       # Rename locally
git push origin --delete old-name     # Delete old remote
git push origin new-name              # Push new remote
Enter fullscreen mode Exit fullscreen mode

Worktrees: Parallel Development

# Why worktrees?
# → Work on two features simultaneously without stashing
# → Test a hotfix while keeping current work intact
# → Run long builds on separate checkouts

# Create worktree
git worktree add ../feature-a feature/branch-a    # New directory, different branch
git worktree add ../hotfix main                    # Start from main

# Now you have three independent working directories:
# ./project/           (your current work)
# ../feature-a/         (feature A development)
# ../hotfix/            (urgent hotfix on main)

# Manage worktrees
git worktree list                               # Show all worktrees
git worktree remove ../feature-a                 # Done with this worktree
git worktree prune                                # Remove stale worktree refs

# Practical workflow:
# 1. Working on feature, urgent bug comes in
# 2. git worktree add ../fix main
# 3. cd ../fix; implement fix; test; commit; push
# 4. cd ../../project; continue where you were
Enter fullscreen mode Exit fullscreen mode

Bisect: Find the Breaking Commit

# When did this bug appear? Don't guess — use bisect!

git bisect start
git bisect bad                           # Current version has the bug
git bisect good v2.0.0                   # This version was fine

# Git will checkout commits automatically.
# For each one, test if the bug exists:

git bisect good                          # This commit is fine
git bisect bad                           # Bug is present here

# Eventually Git tells you exactly which commit introduced the bug:
# abc1234 is the first bad commit
# commit description here...

git bisect reset                         # Done, return to original branch

# Automated bisect (for reproducible bugs):
git bisect start
git bisect bad
git bisect good v2.0.0
git bisect run npm test                  # Auto-run tests on each checkout
# Git finds the breaking commit without manual intervention!
Enter fullscreen mode Exit fullscreen mode

Hooks: Automate Quality Checks

# Hook locations: .git/hooks/
# Enable a hook: copy it and make executable

# Pre-commit (runs before every commit)
#!/bin/bash
# .git/hooks/pre-commit
npm run lint || exit 1                   # Block commit if lint fails
npm run typecheck || exit 1              # Block if types wrong
echo "✅ Pre-commit checks passed"

# Commit-msg (enforce conventional commits)
#!/bin/bash
# .git/hooks/commit-msg
if ! grep -qE "^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: .+" "$1"; then
  echo "❌ Invalid commit message!"
  echo "Format: type(scope): description"
  echo "Types: feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert"
  exit 1
fi

# Pre-push (run tests before pushing)
#!/bin/bash
npm test || {
  echo "❌ Tests failed! Push aborted."
  exit 1
}

# Install hooks automatically (for team):
# npx husky init          # Modern hook manager
# husky add .husky/pre-commit "npm run lint"
# husky add .husky/pre-push "npm test"

# Or use simple-git-hooks (package.json config):
# "simple-git-hooks": { "pre-commit": "npx lint-staged", "pre-push": "npm test" }
Enter fullscreen mode Exit fullscreen mode

Must-Have Aliases

# Add these to ~/.gitconfig [alias] section:
[alias]
  co = checkout
  br = branch
  ci = commit
  st = status
  l = log --oneline --graph -15
  unstage = reset HEAD --
  amend = commit --amend --no-edit
  prune-all = !git remote | xargs -n1 git remote prune
  undo = reset --soft HEAD~1
  diffc = diff --cached
  recent = branch --sort=-committerdate -10
  cleanup = !git branch --merged | grep -v '\\*\\|main\\|develop' | xargs git branch -d

# My daily top 5:
# git co feature/new        → checkout
# git st                     → quick status
# git l                      → pretty graph log
# git recent                 → recently worked branches
# git cleanup                -> delete old merged branches
Enter fullscreen mode Exit fullscreen mode

What's your favorite Git trick? Which one here is new to you?

Follow @armorbreak for more practical developer guides.

Top comments (0)