DEV Community

Alex Chen
Alex Chen

Posted on

Git Commands I Wish I Knew Earlier

Git Commands I Wish I Knew Earlier

These git commands save me time every single day. Learn them now, thank me later.

The Basics Everyone Knows

git init          # Initialize repo
git add .         # Stage changes
git commit -m "msg" # Commit
git push           # Push to remote
git pull           # Pull from remote
git status         # Check status
git diff           # See unstaged changes
git log            # View history
Enter fullscreen mode Exit fullscreen mode

The Commands That Actually Matter

Viewing History (Better Ways)

# Pretty log (my favorite)
git log --oneline --graph --all --decorate
# * a1b2c3d (HEAD -> main) Add feature X
# * e4f5g6h Fix bug Y
# | * i7j8k9l (origin/feature) Feature branch work

# Log with stats (what changed)
git log --stat

# Log for specific file
git log --follow -p src/utils.js    # + show actual diffs!

# Who changed this line?
git blame src/utils.js              # Line-by-line authorship

# Search commits by message
git log --grep="bug fix"           # Commits with "bug fix" in message
git log --grep="auth" --oneline   # Quick list

# Search commits by code change
git log -S "functionName" --oneline  # Commits that added/removed "functionName"
git log -G "pattern" --oneline     # Commits where regex matches diff

# Show commit details
git show a1b2c3d                   # Full diff of one commit
git show a1b2c3d --stat             # Just file summary
Enter fullscreen mode Exit fullscreen mode

Stashing (Save Work Temporarily)

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

# List stashes
git stash list
# stash@{0}: On main: WIP: feature X
# stash@{1}: On main: WIP: other thing

# Restore stash (removes it from list)
git stash pop        # Apply + remove most recent
git stash apply      # Apply but keep in list

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

# Drop a stash (discard)
git stash drop stash@{0}

# Clear all stashes
git stash clear

# Stash with untracked files too
git stash push -u -m "WIP including new files"

# Stash specific files only
git stash push -m "just utils" src/utils.js
Enter fullscreen mode Exit fullscreen mode

Interactive Staging

# Stage parts of a file (NOT the whole file!)
git add -p
# Stage this hunk [y,n,q,a,d,e,?]?
# y = yes, stage this hunk
# n = no, skip this hunk
# q = quit, done staging
# a = stage this and all remaining
# d = don't stage this or any remaining
# e = edit this hunk manually
# ? = help

# Reset parts of a file (unstage specific hunks)
git reset -p

# Commit with interactive staging
git commit -p    # Combines add -p + commit
Enter fullscreen mode Exit fullscreen mode

Undoing Mistakes

# Undo last commit (keep changes staged)
git reset --soft HEAD~1

# Undo last commit (keep changes UNSTAGED)
git reset HEAD~1

# Undo last commit AND discard changes (DANGEROUS!)
git reset --hard HEAD~1

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

# Discard all changes to a file (go back to last commit)
git checkout -- path/to/file
# Or newer:
git restore path/to/file

# Discard ALL uncommitted changes
git restore .
# Or dangerous:
git checkout -- .

# Fix the last commit message (if not pushed yet)
git commit --amend -m "New message"

# Fix something you forgot in the last commit
git add forgotten-file.js
git commit --amend --no-edit   # Keeps same message, adds new file
Enter fullscreen mode Exit fullscreen mode

Branching Done Right

# Create and switch to new branch
git checkout -b feature/new-feature
# Or modern equivalent:
git switch -c feature/new-feature

# List branches (local + remote)
git branch -a
# * main
#   feature/new-feature
#   remotes/origin/main
#   remotes/origin/feature/other

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

# Delete local branch (must not be on it)
git branch -d feature/done       # Safe (checks if merged)
git branch -D feature/abandoned  # Force delete

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

# Compare branches
git diff main...feature        // What changed between main and feature?
git log main..feature          // Commits in feature that aren't in main
git log main..feature --oneline

# Merge vs Rebase
git merge feature-branch        // Merge commit (preserves history)
git rebase main                // Linear history (rewrites commits)

# When to use which:
# Merge: Shared branches (main, develop) — preserves public history
# Rebase: Local feature branches before merging — clean linear history
Enter fullscreen mode Exit fullscreen mode

Cherry-Picking

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

# Cherry-pick without committing (edit first)
git cherry-pick -n a1b2c3d
# Make changes...
git cherry-pick --continue

# Cherry-pick multiple commits
git cherry-pick a1b2c3d e4f5g6h i7j8k9l

# If conflict occurs:
# 1. Resolve conflicts in files
# 2. git add <resolved-files>
# 3. git cherry-pick --continue
# Or abort: git cherry-pick --abort
Enter fullscreen mode Exit fullscreen mode

Bisect (Find Which Commit Broke Something)

# Start bisect (when did this bug appear?)
git bisect start
git bisect bad                  # Current version has the bug
git bisect good v1.0.0          # This version was fine

# Git will check out a middle commit
# You test it:
# git bisect good               # This version is fine → bug is after this
# git bisect bad                # This version has bug → bug is before this

# Repeat until git finds the exact commit!
# Then:
git bisect reset                # Exit bisect mode
Enter fullscreen mode Exit fullscreen mode

Cleaning Up

# Remove untracked files (dry run first!)
git clean -nd                    # n=dry-run, d=show-directories
git clean -fd                    # f=force remove files+dirs

# Remove ignored files too
git clean -fdx                  # x=remove ignored files

# Prune merged local branches
git branch --merged main | grep -v '^\*' | xargs git branch -d

# Garbage collection (clean up orphaned objects)
git gc                           # Full garbage collection
git prune                        # Remove unreachable objects

# Large file storage (LFS for big repos)
git lfs install                  # Initialize LFS
git lfs track "*.psd"            # Track PSD files via LFS
git add .gitattributes
Enter fullscreen mode Exit fullscreen mode

Aliases I Use Daily

[alias]
    co = checkout
    br = branch
    ci = commit
    st = status -sb
    lg = log --oneline --graph --all --decorate -15
    unstage = reset HEAD --
    amend = commit --amend --no-edit
    recent = log --oneline -10
    save = !git add -A && git commit -m \"WIP: $(date +%s)\"
    prune = !git branch --merged main | grep -v '\\*\\|main' | xargs git branch -d
    diffc = diff --cached
    rbc = rebase --continue
    aba = bisect abort
Enter fullscreen mode Exit fullscreen mode

My Workflow Example

# Start new work
git co main && git pull origin main
git co -b feature/user-auth

# ... write code ...
git add -p                    # Review each change
git ci -m "feat(auth): add login form"

# ... more code ...
git add src/auth/login.test.ts
git ci -m "test(auth): add login form tests"

# Sync before pushing
git fetch origin
git rebase origin/main        # Clean history

# Push
git push -u origin feature/user-auth

# After PR merge:
git co main && git pull
git br -d feature/user-auth
git push origin --delete feature/user-auth
Enter fullscreen mode Exit fullscreen mode

Which git command changed your life?

Follow @armorbreak for more developer content.

Top comments (0)