DEV Community

Teguh Coding
Teguh Coding

Posted on

Git Tricks That Will Make Your Team Think You Are a Wizard

I still remember the day a senior engineer on my team committed a single line change and it landed with a perfectly scoped commit message, a clean diff, and zero noise from unrelated files. I had been using Git for two years at that point and I thought I knew it. I did not know it.

That day started a personal obsession with Git that has saved me dozens of hours, impressed multiple teammates, and — once — prevented a production disaster that would have ruined a Monday morning for the entire company.

Here are the tricks I wish someone had shown me on day one.

1. Fixup Commits: The Clean History Superpower

You just pushed a feature branch. Your reviewer replies: "looks good, just fix the typo in the function name." So you make a tiny fix and now your history looks like:

add user authentication
fix tests
wip
fix typo
Enter fullscreen mode Exit fullscreen mode

Hideous. Here is the better way using --fixup:

# Make your fix, then commit it as a fixup to a specific previous commit
git add .
git commit --fixup=HEAD~2

# Then squash everything neatly with autosquash
git rebase -i --autosquash HEAD~4
Enter fullscreen mode Exit fullscreen mode

Git automatically marks the fixup commit and places it right after its target during the interactive rebase. You end up with a clean, logical history with zero manual reordering.

2. git reflog: Your Undo Button for Everything

You did a git reset --hard and lost work. Panic sets in. Stop. Breathe. Open this:

git reflog
Enter fullscreen mode Exit fullscreen mode

You will see something like:

a3f2b1c HEAD@{0}: reset: moving to HEAD~3
7d9e4a2 HEAD@{1}: commit: add payment integration
3c1a8f0 HEAD@{2}: commit: update cart logic
Enter fullscreen mode Exit fullscreen mode

That commit you thought was gone? It is still there. Get it back:

git checkout 7d9e4a2
# or restore your whole branch:
git reset --hard 7d9e4a2
Enter fullscreen mode Exit fullscreen mode

The reflog keeps a record of every place HEAD has pointed for the last 90 days by default. It is your time machine.

3. Partial Staging with git add -p

This one changes how you think about commits entirely. You have been hacking on a feature and also fixed a bug along the way. Both changes are in the same file. Most developers either commit everything together (messy) or manually copy-paste changes (painful).

Instead:

git add -p
Enter fullscreen mode Exit fullscreen mode

Git shows you each "hunk" of changes one at a time and asks what to do:

@@ -14,6 +14,10 @@ function fetchUser(id) {
   const user = await db.findById(id);
+  if (!user) throw new Error('User not found');
   return user;
 }

Stage this hunk [y,n,q,a,d,s,?]?
Enter fullscreen mode Exit fullscreen mode

Hit y to stage, n to skip, s to split the hunk into smaller pieces. You can build a perfectly scoped commit from a file that has five different concerns changed in it.

This is how senior engineers write commits that tell a story.

4. git bisect: Find the Exact Commit That Broke Everything

Something is broken in production. It worked two weeks ago. You have 200 commits between then and now. How do you find the culprit?

Most people start git log scrolling and guessing. The right answer is binary search:

git bisect start
git bisect bad                  # current commit is broken
git bisect good v2.4.0          # this tag was working
Enter fullscreen mode Exit fullscreen mode

Git checks out the midpoint commit. You test it. Then:

git bisect good   # if it works
git bisect bad    # if it is broken
Enter fullscreen mode Exit fullscreen mode

Repeat. Git narrows it down in log2(N) steps. For 200 commits, that is about 8 rounds. You find the exact breaking commit in minutes.

You can even automate it with a test script:

git bisect run npm test
Enter fullscreen mode Exit fullscreen mode

Git runs your test suite at each midpoint and determines good/bad automatically. Walk away and come back to the answer.

5. Stash with a Name (and Stop Losing Stashes)

Everyone uses git stash. Almost nobody uses it well.

# Bad: unnamed stash you will forget in two days
git stash

# Good: named stash you can find later
git stash push -m "WIP: cart discount logic before refactor"
Enter fullscreen mode Exit fullscreen mode

Now when you list stashes:

git stash list
# stash@{0}: On feature/cart: WIP: cart discount logic before refactor
# stash@{1}: On main: hotfix idea for rate limiter
Enter fullscreen mode Exit fullscreen mode

Apply a specific one by name:

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

Bonus: stash only your unstaged changes while keeping the index intact:

git stash push --keep-index
Enter fullscreen mode Exit fullscreen mode

Useful when you want to test if your staged changes work in isolation before committing.

6. git worktree: Work on Two Branches Simultaneously

This is the trick that genuinely surprises people. You are deep in a feature branch. A critical hotfix comes in. You need to switch branches but you do not want to stash or lose your mental context.

Instead of switching, add a worktree:

git worktree add ../hotfix-branch hotfix/payment-bug
Enter fullscreen mode Exit fullscreen mode

This checks out hotfix/payment-branch in a separate folder (../hotfix-branch) while your current folder stays on your feature branch. Two branches. Two directories. One repository. No stashing.

cd ../hotfix-branch
# fix the bug
git commit -am "fix: resolve payment timeout on retry"
cd ../my-feature
# exactly where you left off
Enter fullscreen mode Exit fullscreen mode

Clean up when done:

git worktree remove ../hotfix-branch
Enter fullscreen mode Exit fullscreen mode

7. Smarter git log for Real Insights

The default git log output is verbose and hard to scan. These aliases will change your daily workflow:

# Add to your ~/.gitconfig
[alias]
  lg = log --oneline --graph --decorate --all
  who = log --pretty=format:"%h %an %ar - %s" --no-merges
  changed = diff --stat HEAD~1 HEAD
Enter fullscreen mode Exit fullscreen mode

Now:

git lg          # visual branch graph, compact
git who         # who committed what and when
git changed     # what changed in the last commit
Enter fullscreen mode Exit fullscreen mode

Or search commit messages across the whole history:

git log --all --grep="payment" --oneline
Enter fullscreen mode Exit fullscreen mode

Find when a specific line was introduced (not just when the file changed):

git log -S "calculateDiscount" --oneline
Enter fullscreen mode Exit fullscreen mode

This searches for commits where the string calculateDiscount was added or removed. Incredibly useful for tracking down when a function appeared or disappeared.

8. The Commit Message That Actually Helps Future You

This is not a command, it is a discipline. And it matters more than all the tricks above combined.

A bad commit message:

fix stuff
Enter fullscreen mode Exit fullscreen mode

A good commit message:

fix: prevent double-charge on payment retry

The payment service was not checking for an existing pending transaction
before creating a new one. When a network timeout triggered a retry, users
could be charged twice. Added an idempotency key check before charge creation.

Closes #847
Enter fullscreen mode Exit fullscreen mode

The format that works:

  • First line: short summary, 50 chars or less, imperative mood ("fix", "add", "update")
  • Blank line
  • Body: WHY this change was made, not what (the diff already shows what)
  • Reference tickets/issues

When you or your teammate is debugging at 2 AM six months from now and runs git log, that message is the difference between a clue and a dead end.

Putting It Together

You do not need to memorize all of this today. Pick one trick that solves a pain you feel right now:

  • Messy history on PRs? Start with --fixup and git add -p.
  • Afraid of losing work? Learn git reflog.
  • Hard to find regression bugs? Practice git bisect on a toy project.
  • Context-switching costs killing you? Try git worktree.

Git is not just version control. It is a communication tool for your team across time. The better you use it, the clearer the story of your codebase becomes — and the faster everyone can move.

Which of these was new to you? Is there a Git trick you swear by that is not on this list? Let me know in the comments.

Top comments (0)