DEV Community

z z
z z

Posted on

10 Git Commands I Wish I Learned Sooner

We all learn Git the hard way. You start with add, commit, push — and that works until the day you accidentally commit to main or delete a branch you meant to keep.

Here are 10 Git commands I discovered way later than I should have. Each one saved me from a real mess.

1. git switch — The Safe Checkout

I used git checkout for everything: switching branches, restoring files, creating new branches. Until one day I ran:

git checkout some-file.txt
Enter fullscreen mode Exit fullscreen mode

expecting to switch to a branch, and instead wiped my working directory changes.

git switch separates branch switching from file restoration:

git switch feature-branch      # switch branches
git switch -c new-feature      # create and switch
Enter fullscreen mode Exit fullscreen mode

git restore handles the file side:

git restore some-file.txt      # discard uncommitted changes
Enter fullscreen mode Exit fullscreen mode

Two commands, one job each. No more accidental wipes.

2. git log --oneline --graph — See the Story

Plain git log dumps a wall of text. Add --oneline --graph and you see the actual branch topology:

git log --oneline --graph --all --decorate

* 7a3f92e (HEAD -> main) fix: handle null pointer
| * a8d2c11 (feature-x) feat: add retry logic
|/
* b4e3391 chore: bump deps
Enter fullscreen mode Exit fullscreen mode

I use --all because branches you're not on matter too. Onboard this as an alias:

git config --global alias.tree "log --oneline --graph --all --decorate"
git tree
Enter fullscreen mode Exit fullscreen mode

3. git commit --amend — Edit Without Clutter

Pushed a typo in the last commit message? Forgot to stage that one file?

git add forgotten-file.py
git commit --amend --no-edit      # add file without changing message
git commit --amend -m "Better message"  # fix the message
Enter fullscreen mode Exit fullscreen mode

⚠️ Only amend commits you haven't pushed yet. Once pushed, amend rewrites history and everyone who pulled will hate you.

4. git stash push -m "description" — Named Stashes

Without a message, git stash creates nameless entries. Three stashes later you have no idea which is which.

git stash push -m "WIP: login refactor"
git stash push -m "debug logging experiment"
git stash list
# stash@{0}: On main: debug logging experiment
# stash@{1}: On main: WIP: login refactor

git stash pop stash@{1}
Enter fullscreen mode Exit fullscreen mode

I now write a description every single time — saves me 5 minutes of "which stash was that" every week.

5. git rebase -i — Clean History Before You Share

Your branch has 7 commits that say "wip", "fix", "fix again". Before merging, squash them into one meaningful commit:

git rebase -i HEAD~7
Enter fullscreen mode Exit fullscreen mode

In the editor, change pick to squash (or just s) for the commits you want to merge upward. Keep the first commit's message.

I rebase before every merge. The result is a linear, readable history that your future self and your teammates will thank you for.

6. git bisect — Find the Bug Automatically

A feature that worked last week is broken today. You have 50 commits between "worked" and "broken".

git bisect start
git bisect bad                 # current commit is broken
git bisect good abc123         # this commit worked

# Git checks out a commit in the middle.
# You test it:
git bisect good                # if it works
git bisect bad                 # if it's broken

# Repeat 4-5 times. Git finds the exact commit.
git bisect reset
Enter fullscreen mode Exit fullscreen mode

bisect runs a binary search. 50 commits → ~6 checks. 500 commits → ~9 checks. I use this monthly and it always finds the culprit.

Automate it if you have a test command:

git bisect run npm test
Enter fullscreen mode Exit fullscreen mode

7. git worktree — Work on Two Branches at Once

You're deep in feature-x and someone says "urgent hotfix on main".

Instead of stashing or force-closing your editor:

git worktree add ../hotfix-fix main
cd ../hotfix-fix
# fix the bug, commit, push
cd ..
git worktree remove ../hotfix-fix
Enter fullscreen mode Exit fullscreen mode

Each worktree is a full checkout in its own directory. Open it in another editor tab, work on it, switch back. No stash, no context loss.

I keep 2-3 worktrees active during a typical dev day.

8. git diff --cached — Review Before You Commit

git diff shows unstaged changes. But I want to review what I'm about to commit:

git diff --cached
Enter fullscreen mode Exit fullscreen mode

This shows only the staged diff. It's replaced by the git commit -v experience:

git commit -v    # opens editor with diff in the message area
Enter fullscreen mode Exit fullscreen mode

See exactly what goes in before it goes in. Catches half-baked code every time.

9. git clean -nd — Preview Destructive Deletes

Untracked files accumulate: build artifacts, .env.bak, node_modules you somehow regenerated.

git clean -nd
# Would remove .env.bak
# Would remove dist/
Enter fullscreen mode Exit fullscreen mode

The -n flag is a dry run. -d targets directories. When you're sure:

git clean -fd
Enter fullscreen mode Exit fullscreen mode

I never run git clean without -n first. Too many stories of someone nuking a folder they needed two days ago.

10. git blame --ignore-revs-file — Skip Formatting Commits

git blame is the first thing I reach for when I see weird code. But auto-formatters and mass renames pollute the blame, pointing at the person who ran prettier instead of the person who wrote the bug.

# Save a file listing commits that are "noise"
echo "abc123def" > .git-blame-ignore-revs
git blame --ignore-revs-file .git-blame-ignore-revs main.py
Enter fullscreen mode Exit fullscreen mode

Commit your .git-blame-ignore-revs file to the repo so everyone benefits. GitHub even respects it natively when viewing blame on pull requests.


These 10 commands won't make you a Git guru overnight. But they'll save you from the specific, painful moments we all hit: accidental deletions, messy histories, broken branches, and wasted hours tracking down bugs.

Start with one: alias git tree and run it on your current project. See your branches differently.

Have a Git command that made you say "I wish I learned this sooner"? Drop it in the comments.

Top comments (0)