12 Git Tricks That Made Me a Way Better Developer

From stashing changes to interactive rebasing, learn practical commands that solve real-world coding problems and help you manage complex repositories with confidence.

November 24, 2025
13 min read
12 Git Tricks That Made Me a Way Better Developer

When I first started using Git, I only knew the basics. Clone, add, commit, push. That was my entire toolkit.

But as my projects grew bigger, I hit roadblocks. I needed more than just the basics.

Over time, I discovered Git tricks that completely changed how I work. These aren't fancy or complex. They're practical commands that solve real problems.

Here are 12 Git tricks that made me a better developer.

1. Git Stash: Your Secret Workspace Saver

Have you ever been deep in coding when suddenly you need to switch branches? But your work isn't ready to commit yet.

This happened to me all the time. I'd panic and make messy commits just to switch tasks.

Then I learned about git stash.

How It Works

Git stash temporarily saves your uncommitted changes. It cleans your working directory. You can switch branches freely. Later, you bring those changes back.

Think of it as a clipboard for your code.

Basic Commands

Save your current work:

git stash

See all your stashes:

git stash list

Bring back your latest stash:

git stash pop

Apply a specific stash:

git stash apply stash@{0}

Pro Tip: Name Your Stashes

Don't just stash blindly. Give your stashes meaningful names.

git stash push -m "WIP: homepage redesign"

Now when you run git stash list, you'll see:

stash@{0}: On main: WIP: homepage redesign

Much better than generic stash messages!

This trick saved me countless times when emergencies popped up. I could switch context without losing work or making half-baked commits.

2. Interactive Rebase: Clean Up Your Commit History

My early commit history was a mess. "fix typo", "actually fix typo", "fix again". Not professional at all.

Interactive rebase changed everything.

What It Does

Interactive rebase lets you edit, combine, or reorder commits before pushing. You can squash multiple commits into one. You can reword commit messages. You can even delete commits.

How to Use It

Let's say you want to clean up your last 5 commits:

git rebase -i HEAD~5

Git opens an editor showing your commits:

pick a12345 Add login feature
pick b23456 Fix typo in login
pick c34567 Add logout button
pick d45678 Fix logout bug
pick e56789 Update README

Available Commands

  • pick: Keep the commit as is
  • reword: Change the commit message
  • squash: Combine with previous commit
  • fixup: Like squash, but discard this message
  • drop: Remove the commit entirely

Example: Squashing Commits

Change your file to:

pick a12345 Add login feature
squash b23456 Fix typo in login
pick c34567 Add logout button
squash d45678 Fix logout bug
pick e56789 Update README

Save and close. Git combines the commits you marked.

Now instead of 5 messy commits, you have 3 clean ones. Your commit history tells a clear story.

3. Cherry-Pick: Grab Specific Commits

Sometimes you need just one commit from another branch. Not the whole branch. Just that one fix.

Cherry-pick does exactly that.

The Scenario

You're working on feature-branch. Someone fixed a critical bug on hotfix-branch. You need that fix now. But you don't want to merge the entire hotfix branch.

How to Cherry-Pick

First, find the commit hash:

git log hotfix-branch --oneline

Let's say the commit hash is abc1234.

Switch to your branch:

git checkout feature-branch

Cherry-pick that commit:

git cherry-pick abc1234

Done! That specific commit is now on your branch.

Cherry-Pick Multiple Commits

Need several commits?

git cherry-pick abc1234 def5678 ghi9012

Or use a range:

git cherry-pick abc1234^..ghi9012

This applies all commits from abc1234 to ghi9012.

Cherry-picking is perfect for applying bug fixes across multiple branches without unnecessary merges.

4. Git Reflog: Recover Lost Commits

I once accidentally deleted an important branch. My heart sank. Hours of work, gone.

Then I discovered git reflog. It saved me.

What Is Reflog?

Reflog tracks every change to your repository's HEAD. Every commit, reset, checkout, merge—everything.

Even if you delete a commit or branch, reflog remembers it.

How to Use Reflog

View your reflog:

git reflog

You'll see output like:

a1b2c3d HEAD@{0}: commit: Add new feature
e4f5g6h HEAD@{1}: checkout: moving to main
i7j8k9l HEAD@{2}: commit: Fix bug

Recovering a Lost Commit

Found the commit you need? Use its hash:

git checkout a1b2c3d

Or create a new branch from it:

git checkout -b recovered-branch a1b2c3d

Recovering a Deleted Branch

Let's say you deleted feature-branch by mistake.

Find it in reflog:

git reflog | grep feature-branch

Create it again:

git checkout -b feature-branch <commit-hash>

Reflog is your safety net. It's saved me more times than I can count.

5. Git Bisect: Find Bugs Fast

A bug appeared in production. But you have 100 commits since the last working version. Which commit broke it?

Checking each commit manually would take forever.

Git bisect does it in minutes.

How Bisect Works

Bisect uses binary search. It cuts the commit range in half each time. You just tell it "good" or "bad".

With 100 commits, you'll only test about 7.

Using Bisect

Start bisect:

git bisect start

Mark the current (broken) commit as bad:

git bisect bad HEAD

Mark a known good commit:

git bisect good abc1234

Git checks out a commit halfway between them.

Test it. If the bug exists:

git bisect bad

If it works fine:

git bisect good

Git keeps narrowing it down. Eventually, it tells you exactly which commit introduced the bug.

When done:

git bisect reset

This returns you to your original branch. Bisect is incredibly powerful for debugging. It turns hours of work into minutes.

6. Git Worktree: Work on Multiple Branches Simultaneously

Switching branches constantly is annoying. You have to stash changes. Clean your workspace. Switch. Then do it all again.

Git worktree solves this.

What Is Worktree?

Worktree lets you check out multiple branches in different directories. All linked to the same repository.

You can work on a feature in one folder while fixing a bug in another. No switching needed.

Creating a Worktree

From your main repository:

git worktree add ../feature-work feature-branch

This creates a new directory ../feature-work with feature-branch checked out.

Your main directory stays on its current branch.

List All Worktrees

git worktree list

Remove a Worktree

When done:

git worktree remove ../feature-work

Real-World Use Case

I use worktrees when reviewing pull requests. I keep my main work in one directory. I check out the PR in a worktree. I can compare them side-by-side.

No more constant switching. No more lost context.

7. Git Aliases: Create Custom Shortcuts

Typing long Git commands gets tedious. Especially ones you use constantly.

Git aliases let you create shortcuts.

Setting Up Aliases

Use git config:

git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status

Now instead of git checkout, just type:

git co

More Useful Aliases

A beautiful one-line log:

git config --global alias.lg "log --oneline --graph --decorate --all"

Now git lg shows:

* a1b2c3d (HEAD -> main) Add feature
* e4f5g6h Fix bug
* i7j8k9l Initial commit

Uncommit last commit (keep changes):

git config --global alias.uncommit "reset --soft HEAD~1"

See what you're about to commit:

git config --global alias.review "diff --staged"

Editing Config File

You can also edit ~/.gitconfig directly:

[alias]
    co = checkout
    br = branch
    ci = commit
    st = status
    lg = log --oneline --graph --decorate --all
    uncommit = reset --soft HEAD~1
    review = diff --staged

Aliases save so much time. Create shortcuts for commands you use daily.

8. Git Diff: Compare Changes Like a Pro

Understanding what changed is crucial. git diff helps you see exactly what's different.

Unstaged vs Staged Changes

By default, git diff shows unstaged changes:

git diff

This compares your working directory to the staging area.

To see staged changes (what you're about to commit):

git diff --staged

Or use the older syntax:

git diff --cached

Compare Branches

See differences between branches:

git diff main..feature-branch

Compare Commits

git diff abc1234 def5678

Compare a Specific File

git diff HEAD path/to/file.js

Pro Tip: See Both Staged and Unstaged

Want to see everything at once?

git status -vv

This shows both staged and unstaged diffs in one view.

Understanding git diff variations helps you review changes thoroughly before committing.

9. Git Blame: Track Code History

When you find confusing code, you need context. Who wrote it? When? Why?

git blame answers these questions.

Basic Blame

git blame path/to/file.js

You'll see output like:

a1b2c3d (John Doe 2024-01-15) function login() {
e4f5g6h (Jane Smith 2024-02-20)   validateUser();
i7j8k9l (John Doe 2024-01-15)   return true;

Each line shows who last modified it and when.

Blame Specific Lines

Only check lines 10-20:

git blame -L 10,20 path/to/file.js

View the Full Commit

Found the commit hash? See what else changed:

git show a1b2c3d

Not About Blaming

Despite the name, git blame isn't about blaming people. It's about understanding code history.

I use it to find context. Reading the commit message often explains why code exists.

10. Git Hooks: Automate Your Workflow

Git hooks run scripts automatically at specific times. Before commits. Before pushes. After merges.

They automate repetitive tasks.

Where Are Hooks?

Look in .git/hooks/ in your repository.

You'll find sample files. Remove .sample extension to activate them.

Common Hooks

  • pre-commit: Runs before commit completes
  • commit-msg: Checks commit message format
  • pre-push: Runs before push
  • post-merge: Runs after merge

Example: Pre-Commit Hook

Create .git/hooks/pre-commit:

#!/bin/bash

echo "Running tests before commit..."

npm test

if [ $? -ne 0 ]; then
    echo "Tests failed! Commit aborted."
    exit 1
fi

Make it executable:

chmod +x .git/hooks/pre-commit

Now Git runs your tests before every commit. If tests fail, the commit is blocked.

Example: Enforce Commit Message Format

Create .git/hooks/commit-msg:

#!/bin/bash

commit_message=$(cat "$1")

if ! [[ $commit_message =~ ^[A-Z] ]]; then
    echo "Commit message must start with a capital letter!"
    exit 1
fi

This enforces capitalization in commit messages.

Using Husky for Shared Hooks

Manual hooks aren't shared in Git. Use Husky to share hooks with your team.

Install Husky:

npm install --save-dev husky

Set it up:

npx husky init

Now everyone on your team uses the same hooks.

Hooks enforce standards automatically. No more forgetting to run tests or linters.

11. Git Reset: Three Modes You Must Know

git reset moves your branch to a different commit. But it has three modes that behave very differently.

Understanding them prevents disasters.

The Three Modes

ModeHEADStaging AreaWorking Directory
--softMovesUnchangedUnchanged
--mixedMovesResetUnchanged
--hardMovesResetReset

Soft Reset

Undo commits but keep changes staged:

git reset --soft HEAD~1

This removes the last commit. But your changes stay in staging. You can re-commit them.

Use this when you want to re-do a commit.

Mixed Reset (Default)

Undo commits and unstage changes:

git reset HEAD~1

Or explicitly:

git reset --mixed HEAD~1

Changes move back to working directory. You can edit them before re-staging.

Use this to reorganize what goes in each commit.

Hard Reset

Completely discard changes:

git reset --hard HEAD~1

Warning: This deletes uncommitted work permanently.

Use this carefully. Only when you're certain you want to discard everything.

Quick Reference

Think of it this way:

  • --soft: Undo git commit
  • --mixed: Undo git commit and git add
  • --hard: Undo everything including file changes

Know these modes. They'll save you when things go wrong.

12. Git Clean: Remove Untracked Files

Sometimes your repository fills with untracked files. Build artifacts. Temp files. Log files.

They clutter your workspace.

What Are Untracked Files?

Files Git doesn't track. They're not in .gitignore. They're not committed. They just... exist.

See What Would Be Deleted

Always preview first:

git clean -n

The -n flag does a "dry run". It shows what would be deleted without actually deleting.

Remove Untracked Files

Force removal:

git clean -f

Remove Untracked Directories Too

git clean -fd

The -d flag includes directories.

Remove Ignored Files

This removes even files in .gitignore:

git clean -fx

Careful: This deletes ignored files like node_modules/.

Interactive Mode

Want more control?

git clean -i

Git asks what to delete interactively.

When to Use Git Clean

I use git clean -fd when:

  • Switching between major branches with different build configs
  • Cleaning up after failed builds
  • Removing generated files before committing

Always run -n first. Double-check what you're deleting.

Bonus: Understanding Fetch vs Pull

This isn't really a trick, but it confused me for years.

Git Fetch

Downloads changes from remote. Doesn't merge them.

git fetch origin

Your remote-tracking branches update (origin/main). But your local branch doesn't change.

Safe. You can review changes before merging.

Git Pull

Downloads AND merges in one command.

git pull origin main

This equals:

git fetch origin
git merge origin/main

Convenient but potentially risky. Can cause unexpected merge conflicts.

Which Should You Use?

I prefer git fetch for safety.

I fetch first. Review the changes. Then merge manually when ready.

But on simple projects, git pull works fine.

Just understand what each does.

Wrapping Up

These 12 tricks transformed how I use Git.

I went from constantly panicking about mistakes to confidently managing complex repositories.

You don't need to memorize everything at once. Start with the tricks that solve your immediate problems.

Having merge conflicts? Learn interactive rebase.

Constantly switching contexts? Try git stash or worktree.

Lost a commit? Learn reflog.

Git is powerful. These tricks unlock that power.

Your future self will thank you.

Quick Reference Table

TrickCommandUse Case
Stashgit stashSave work temporarily
Interactive Rebasegit rebase -i HEAD~5Clean commit history
Cherry-Pickgit cherry-pick abc123Copy specific commits
Refloggit reflogRecover lost commits
Bisectgit bisect startFind bug-introducing commits
Worktreegit worktree addWork on multiple branches
Aliasesgit config --global alias.co checkoutCreate shortcuts
Diff Stagedgit diff --stagedReview before commit
Blamegit blame file.jsTrack code history
HooksCreate files in .git/hooks/Automate workflows
Reset Softgit reset --soft HEAD~1Undo commit, keep changes
Cleangit clean -fdRemove untracked files

Master these tricks. They'll make you a better developer.

Happy coding!