Fundamentals 17 min read

6 Advanced Git Commands Senior Developers Use Daily

This article details six advanced Git commands—git switch, git restore, git stash push -m, git reflog, git add -p, and git bisect—that senior developers rely on for precise branch management, commit recovery, partial staging, and binary-search debugging, with practical examples and workflow comparisons.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
6 Advanced Git Commands Senior Developers Use Daily

Introduction

A junior developer might spend an hour manually undoing a bad commit by opening every changed file and reverting line by line. A senior developer solves the same problem in three seconds with a single command: git reset HEAD~1. Git is a daily tool, yet few learn its proper usage beyond add, commit, push, pull, and merge. When things go wrong, panic sets in. The following six commands are what experienced engineers reach for first—not secrets, just never taught.

2.1 git switch & git restore: Replace the Overloaded checkout

For years git checkout did four unrelated things: switch branches, create branches, restore files, and—if given a wrong argument—detach HEAD. One command handling four tasks is a design flaw that causes lost work. Git 2.23 split this into two focused commands: git switch — only changes branches git restore — only restores files to a previous state

Old way:

git checkout main
git checkout -b feature/login

New way:

git switch main
git switch -c feature/login

Both pairs function identically, but git switch cannot accidentally overwrite files. The danger of checkout appears when restoring files:

# Old: discard changes in a file
git checkout -- src/App.java
# New: discard changes in a file
git restore src/App.java
# Unstage a file but keep changes
git restore --staged src/App.java
# Restore file to state two commits ago
git restore --source=HEAD~2 src/App.java

Summary: Use switch for branches, restore for files. Stop using checkout for both.

2.2 git stash push -m: Name Your Stashes

git stash

shelves uncommitted work so you can switch contexts, giving you a clean working directory. Most developers only know git stash and git stash pop. That works for one or two stashes, but after three you see:

stash@{0}: WIP on feature-login: 4f2a1b3 Add login form
stash@{1}: WIP on feature-login: 4f2a1b3 Add login form
stash@{2}: WIP on main: 9c8d7e6 Fix typo

Which stash holds the unfinished payment logic? You can't tell, so you randomly pop stashes. git stash is actually a named, browsable stack—just give entries meaningful labels:

git stash push -m "支付重试逻辑"
git stash list
# Output:
stash@{0}: On feature-payments: 支付重试逻辑
stash@{1}: On feature-login: 登录表单验证

Now every entry shows its purpose. git stash list displays the stack newest-first; stash@{n} is the index to reference any entry. You don't have to take the top one:

# Inspect before applying
git stash show -p stash@{1}
# Apply specific stash and remove from stack
git stash pop stash@{1}
# Apply but keep in stack as backup
git stash apply stash@{1}

Summary: Name your stashes and the stack never becomes a graveyard.

2.3 git reflog: The Safety Net You Didn't Know Existed

reflog

records every position your local HEAD has pointed to—commits, checkouts, resets, merges, branch switches—even when no branch currently points there. "Lost" commits usually aren't gone; they're just unreachable from any branch. Classic panic: you run git reset --hard HEAD~3 and delete three commits you meant to keep. git log shows them gone. Run git reflog:

git reflog
a1b2c3d HEAD@{0}: reset: moving to HEAD~3
f9e8d7c HEAD@{1}: commit: 为支付服务添加重试逻辑
3b4c5d6 HEAD@{2}: commit: 添加支付超时配置
8d7c6b5 HEAD@{3}: commit: 添加支付服务骨架

All commits remain. The top line is your reset; f9e8d7c is where you were before the mistake. Recover:

git checkout f9e8d7c
git switch -c rescued-payment-work

First command puts you at that commit in detached HEAD; second creates a branch so work has a home again. Alternatively, git reset --hard f9e8d7c moves the current branch pointer directly. Same method restores deleted branches: find the last commit the branch pointed to in reflog, then git branch recovered <hash>. reset --hard is only dangerous when you don't know reflog; once you do, it's a fast, reversible way to discard a failed experiment. Two limits:

Reflog is local—never leaves your machine; a fresh clone lacks your history.

Entries expire—unreachable commits expire after ~30 days by default. Recover quickly, not next quarter.

2.4 git add -p: Stage Only Part of a File

Staging selects what goes into the next commit. Most developers run git add . or git add file.js, staging entire files. Real work is messy: you fix a bug but also rename a variable and add debug logging in the same file—three unrelated changes. git add -p (p = patch) lets you stage individual hunks. Git splits your diff into hunks and prompts for each: git add -p Example prompt:

@@ -12,7 +12,7 @@ public class PaymentService {
-   int maxRetries = 3;
+   int maxRetries = 5;
Stage this hunk [y,n,q,a,d,s,e,?]?

Options: y — stage this hunk n — skip this hunk s — split hunk into smaller hunks (critical when unrelated changes sit together) e — manually edit the hunk q — quit, leave remaining hunks unstaged ? — show help

After selecting hunks, verify what you actually staged:

git diff --staged
git commit -m "Increase payment retry limit"
git diff --staged

shows exactly what the commit will contain. Skipped changes stay in the working directory for the next commit. This produces focused, review-friendly commits—reviewers read single-change commits faster and catch more issues, and you gain a truly searchable history.

2.5 git bisect: Binary Search for the Bug-Introducing Commit

A feature broke; it worked last month. Two hundred commits later, you have no clue which one caused it. The usual guess-and-check through history is slow. git bisect replaces guessing with binary search: it checks out the middle commit, you test, then Git halves the range again. You need two known points: a bad commit (current) and a good commit (earlier tag, hash, or branch).

git bisect start
git bisect bad          # current commit is broken
git bisect good v1.4.0  # this old tag works
# Bisecting: 99 revisions left (roughly 7 steps)
[c4d5e6f] 重构订单校验逻辑

Git checks out the midpoint. Run your app or tests, then tell Git the result:

git bisect good   # this commit works → bug is later
# or
git bisect bad    # this commit broken → bug is earlier

Each answer halves the remaining range. After a few rounds Git stops and identifies the culprit:

a7b8c9d is the first bad commit
commit a7b8c9d
Author: ...
Date: ...
    Switch discount calculation to BigDecimal

When done, always run: git bisect reset This returns you to the original branch.

2.6 git log --oneline --graph: See the History Structure

Default git log is a wall of text—full hashes, authors, dates, messages—with no branch structure visible. Three flags reveal the topology: git log --oneline --graph --all Example output:

*   e4f5a6b (HEAD -> main) Merge branch 'feature/search'
|\
| * 7c8d9e0 (feature/search) Add search filters
| * 3b4c5d6 Add search endpoint
|/
| * 5d6e7f8 (hotfix/login) Fix login redirect
|/
* a1b2c3d Update README
* 9f8e7d6 Initial project setup
--oneline

compresses each commit to short hash + message. --graph draws branch lines with ASCII characters. --all includes every branch, not just the current one.

You can see feature/search branched from main and later merged back. hotfix/login is an unmerged branch; its fork point is clear. Before merging or rebasing, you understand the actual layout—whether a branch is ahead or behind, and spot forgotten orphan branches. Running this once clears most "what happened in this repo?" confusion. Create an alias to avoid typing the full command:

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

Now just type git lg.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Gitversion controlgit stashgit restoregit switchgit refloggit bisectgit add -p
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.