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)

Most developers know add, commit, push. But Git has so much more power. These are the commands that changed how I work.

Rewriting History (Use with Care!)

# Modify your LAST commit (most useful command ever!)
# Forgot a file? Typo in commit message? This fixes it:
git add forgotten-file.js
git commit --amend -m "Fixed commit message"

# Reorder, squash, or split recent commits:
git rebase -i HEAD~3    # Interactive rebase of last 3 commits
# Opens editor with options:
# pick = use commit as-is
# reword = change message only
# edit = pause to modify files
# squash = merge into previous commit
# fixup = merge into previous (discard message)
# drop = remove entirely

# Example: Squash last 3 "WIP" commits into one clean commit:
# Change first to "pick", rest to "squash"
# Save → Git opens editor for combined message

# Update a commit message from earlier (not just the last):
git rebase -i HEAD~5
# Find the commit → change "pick" to "reword"
# Save → edit each message

# Split one commit into two:
git rebase -i HEAD~3
# Find target commit → change "pick" to "edit"
# Git pauses at that commit:
git reset HEAD~1          # Unstage but keep files
git add file1.js
git commit -m "Part 1: file1 changes"
git add file2.js
git commit -m "Part 2: file2 changes"
git rebase --continue     # Continue rebasing
Enter fullscreen mode Exit fullscreen mode

Stashing: Save Work Without Committing

# The basic stash (saves all modified/tracked files):
git stash
# Your working directory is now clean! Go work on something else.

# List all stashes:
git stash list
# Output: stash@{0}: WIP on feature-login: abc1234
#        stash@{1}: WIP on main: def5678

# Restore most recent stash:
git stash pop          # Apply and remove from stash list
git stash apply        # Apply but keep in stash list (safer)

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

# Stash with a name (essential when you have multiple stashes):
git stash push -m "WIP: OAuth implementation half-done"

# Stash untracked files too (new files not yet added):
git stash push -u -m "Including new files"

# Stash specific files only:
git stash push -m "Only config changes" src/config.js .env.example

# Show what's in a stash before applying:
git stash show -p stash@{0}   # Full diff of the stash

# Drop or clear stashes:
git stash drop stash@{0}      # Remove one
git stash clear               # Remove ALL stashes
Enter fullscreen mode Exit fullscreen mode

Searching Through History

# Search COMMIT MESSAGES across all branches:
git log --all --grep="bug fix"   # Find commits mentioning "bug fix"
git log --all --grep="auth" --oneline  # Compact view

# Search CODE CONTENT through history:
git log -S "functionName" --oneline    # When was this text added/removed?
git log -G "pattern" --oneline         # Regex search through diffs
git log -p -S "TODO"                   # Show actual diff where text appears

# Search current codebase:
git grep "error"                # Search all tracked files for "error"
git grep -n "export" src/       # With line numbers, in specific dir
git grep --count "import" ./src/   # Count matches per file

# Who wrote this line? (blame!)
git blame src/utils.js          # Line-by-line author history
git blame -L 10,20 src/utils.js # Lines 10-20 only
git blame -e src/utils.js       # Include email addresses

# Find which commit broke something:
git bisect start
git bisect bad                  # Current version is broken
git bisect good v2.0.0         # This version worked
# Git automatically checks out middle commits
# After each checkout: test, then:
git bisest good                 # This version works
git bisect bad                  # This version is broken
# Repeat until Git finds the exact breaking commit!
git bisect reset                # Done — return to original branch
Enter fullscreen mode Exit fullscreen mode

Branch Management Like a Pro

# See all branches with last commit info:
git branch -vv
# Output: * feature-auth abc1234 [origin/feature-auth] Add OAuth login
#         main           def5678 [origin/main] Release v2.0

# Rename branch (local + remote):
git branch -m old-name new-name
git push origin :old-name new-name  # Delete remote old, push new
# Others need: git fetch --prune && git branch -u origin/new-name new-name

# Compare branches:
git log main..feature-branch --oneline  # Commits in feature but not in main
git log feature-branch..main --oneline  # Commits in main but not in feature
git diff main...feature-branch         # Diff from merge base (not common ancestor)

# Merge vs Rebase (quick reference):
git merge feature-branch              # Creates merge commit, preserves history
git rebase main                       # Linear history, replays commits on top of main

# Safe force-push (only if nobody else pushed to this branch):
git push --force-with-lease origin feature-branch
# Safer than regular --force because it checks if remote changed

# Recover a deleted branch:
git reflog                           # Find the SHA of the branch tip
git branch recovered-branch abc1234  # Recreate branch at that SHA
Enter fullscreen mode Exit fullscreen mode

Working with Remote Repositories

# See all remotes:
git remote -v

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

# Fetch from a specific remote without merging:
git fetch upstream
git log HEAD..upstream/main --oneline  # What's new upstream?

# Track a new remote branch:
git checkout --track origin/new-feature
# Same as: git checkout -b new-feature origin/new-feature

# Clean up stale remote-tracking branches:
git fetch --prune
# Or: git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -d

# Push to multiple remotes simultaneously:
git remote set-url --add --push all git@github:user/repo.git
git remote set-url --add --push all git@gitlab:user/repo.git
git push all main              # Pushes to both GitHub and GitLab!

# Cherry-pick specific commits:
git cherry-pick abc1234                    # Apply one commit from another branch
git cherry-pick abc1234 def5678            # Apply multiple commits
git cherry-pick --no-commit abc1234       # Apply changes without committing
git cherry-pick --edit abc1234            # Edit commit message before applying
Enter fullscreen mode Exit fullscreen mode

Troubleshooting Common Problems

# ❌ Committed to wrong branch:
git reset --soft HEAD~1        # Undo commit, keep changes staged
git checkout correct-branch
git commit                     # Re-commit on correct branch

# ❌ Accidentally committed sensitive data (passwords, keys):
# Option A: If NOT yet pushed:
git rm secrets.json
git commit -m "Remove secrets"
# Use git-filter-repo or BFG Repo Cleaner if already pushed!

# ❌ Merge conflict hell:
# Don't panic. Step by step:
git status                      # See conflicted files
# Open each file, look for: <<<<<<< HEAD, =======, >>>>>>> feature
# Edit to keep what you want, remove markers
git add resolved-file.js        # Mark as resolved
git commit                      # Complete the merge
# Pro tip: use VS Code's merge tool or git mergetool

# ❌ Need to undo something?
git restore file.txt             # Discard working directory changes (uncommitted)
git restore --staged file.txt    # Unstage (keep changes)
git reset --hard HEAD~1          # DANGEROUS: Remove last commit AND changes!
git reflog                       # Recovery mode: find lost commits here

# ❌ Large file slowing down repo:
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sort -rnk3 | head -20
# Find large objects, then use BFG Repo Cleaner or git filter-repo
Enter fullscreen mode Exit fullscreen mode

Which Git command here is new to you? What's your favorite Git trick that wasn't included?

Follow @armorbreak for more practical developer guides.

Top comments (0)