mailwal

🔥 10 Advanced Git Commands Every Developer Should Master

Arvind Verma

🔥 10 Advanced Git Commands Every Developer Should Master

Work smarter. Debug faster. Recover from mistakes. Master your Git history like a production engineer.

Git is easy when everything works.

You create a branch, write code, commit your changes, push to GitHub, and open a pull request. The workflow feels simple enough that you might wonder why experienced developers spend so much time discussing Git.

Then production breaks.

A developer accidentally resets a commit. A bug appears after a deployment, but nobody remembers which commit introduced it. Your feature branch contains several messy commits. You need one fix from another branch without merging everything. Or your working directory is full of unfinished changes when an urgent production issue arrives.

Suddenly, knowing git add, git commit, and git push is not enough.

The real value of Git appears when something goes wrong. The right command can help you recover lost work, identify a faulty change, reorganize a branch, or investigate a production incident without creating another problem.

In this article, we will explore 10 advanced Git commands, understand how they work, examine practical scenarios, and learn the mistakes that developers should avoid. 🚀


PART 1: Recover Work and Investigate Bugs

1. git reflog: Your Time Machine for Git

Have you ever reset a branch and then realised that you needed the commit you just removed?

Most developers immediately assume their work is gone. Sometimes it is not.

Git maintains a reference log, or reflog, that records changes to references such as HEAD. It can help you locate commits that are no longer reachable through your current branch history.

How does it work?

Start by examining your recent reference history:

git reflog

Example output:

9f7c21a HEAD@{0}: reset: moving to HEAD~3
8a6e3b1 HEAD@{1}: commit: Add payment logic
3c7d812 HEAD@{2}: commit: Implement service

Suppose you accidentally moved your branch backwards by three commits. The reflog may show the earlier commit you want to recover.

Inspect it first:

git show 8a6e3b1

If you want to move the current branch back to that commit, you can use:

git reset --hard 8a6e3b1

Be careful: git reset --hard changes the working tree and index, potentially discarding uncommitted work. Confirm the target commit and preserve any valuable changes before using it.

A safer way to preserve the recovered commit is to create a branch pointing to it:

git branch recovery-branch 8a6e3b1

You can then inspect the branch before deciding what to do next.

Real-world scenario

You have spent two days implementing a payment feature. While cleaning up your branch, you run a reset command against the wrong commit.

Instead of immediately rewriting more history, you inspect git reflog, identify the previous commit, and create a recovery branch.

That is a much better incident response than randomly running Git commands and hoping the repository forgives you.

Common interview trap

git reflog is not a permanent backup system. Reflog entries can expire, and unreachable objects can eventually be removed by garbage collection.

Remember: When a commit seems lost, inspect the reflog before assuming it is gone.

2. git stash: Pause Your Work Without Losing It

Imagine you are working on a feature when your team reports a production bug. You need to switch branches immediately, but your current changes are incomplete.

Committing unfinished code just to change branches can create unnecessary commits and complicate collaboration.

This is where git stash helps.

Save your current changes

git stash push -m "WIP payment feature"

Git saves eligible working-tree and index changes so you can return to a cleaner working state.

Switch to the branch containing the urgent fix:

git switch main
git switch -c hotfix/payment

After resolving the production issue, return to your feature branch:

git switch feature/payment
git stash list

Restore your saved changes:

git stash pop

Alternatively, use git stash apply when you want to restore the changes without immediately removing that stash entry.

Useful stash commands

# Show saved stashes
git stash list

# Preview the latest stash
git stash show -p

# Apply without dropping the stash
git stash apply

# Delete a stash entry
git stash drop

Important detail

By default, Git stash primarily saves tracked-file changes. Untracked files require an option such as -u:

git stash push -u -m "WIP including untracked files"

Ignored files require additional care and are not included by that option.

Production scenario

A developer is halfway through a feature when a critical issue needs immediate attention. They stash their changes, switch to the hotfix branch, fix and test the issue, and then resume the feature.

The production fix remains separate from the unfinished feature work.

Remember: Stashing is temporary storage, not a substitute for committing and pushing important work.

3. git cherry-pick: Take One Commit Without Merging Everything

Sometimes a fix exists on one branch, but you need that exact change on another branch.

For example, a developer fixes a payment validation bug in the develop branch. The same fix is urgently needed on main, but merging all of develop would bring unrelated changes.

Use git cherry-pick.

Step 1: Find the commit

git log --oneline develop

Example:

a72c8e1 Fix payment validation
b61d9a4 Add checkout metrics
c91f7d2 Refactor payment service

Step 2: Switch to the target branch

git switch main

Step 3: Apply the required commit

git cherry-pick a72c8e1

Git applies the changes introduced by that commit to the current branch and creates a new commit.

What if there is a conflict?

Inspect the conflicting files, resolve the conflict, and stage the corrected versions:

git status
git add <resolved-file>
git cherry-pick --continue

If you need to abandon the cherry-pick operation:

git cherry-pick --abort

Real-world scenario

A critical security fix has been merged into a development branch, but the production release needs that fix before the next feature release.

Cherry-picking can move the specific fix into the release branch without merging every development change.

However, verify dependencies. A commit may rely on code that exists only in the original branch.

Remember: Cherry-pick copies a commit’s change, not the entire branch.

4. git bisect: Find the Commit That Introduced a Bug

Your application worked last week. Today, a test fails.

There are 100 commits between the last known good release and the first bad build. Reviewing every commit manually would be a tedious use of a developer’s remaining patience.

Git bisect helps narrow the search using binary search.

Step 1: Start the investigation

git bisect start

Mark the current commit as bad:

git bisect bad

Mark a known working commit as good:

git bisect good v1.2.0

Git checks out a commit between those points.

Step 2: Test the selected commit

Run the relevant test or reproduce the bug.

If the application fails:

git bisect bad

If the application works:

git bisect good

Git narrows the search until it identifies the commit that introduced the regression, assuming the good and bad boundaries are accurate and the test reliably distinguishes them.

Step 3: Finish

git bisect reset

This exits bisect mode and returns you to the previous checkout.

Why is it useful?

With a reliably testable regression across 128 commits, binary search can typically narrow the candidate down in about seven comparisons because (2^7 = 128).

That is much faster than checking every commit individually.

Common interview trap

Bisect depends on accurate test results. If a commit cannot be tested, or the failure is intermittent, you may need to mark a revision as skipped or improve the test before continuing.

Remember: Bisect helps answer one important question: Which commit introduced the bug?

5. git blame: Find Who Changed a Line and When

When investigating a production issue, you often need to understand the history of a particular line of code.

git blame shows the commit associated with each line in a file, along with information such as the author and commit date.

git blame UserService.java

To inspect a smaller section:

git blame -L 20,40 UserService.java

Example output might associate a line with a commit that changed the validation logic.

You can then inspect the commit:

git show <commit-hash>

Production scenario

A user reports that a validation rule has started rejecting legitimate requests. You use git blame to locate the commit associated with the relevant lines, then use git show to understand the surrounding change.

The goal is to discover the technical reason behind the behaviour, not to turn a debugging session into a blame game. The command’s name is already doing enough of that.

Important limitation

The person shown by git blame is not necessarily the person who caused the bug. A line may have been moved, copied, refactored, or changed later.

Remember: Use blame to trace code history, then investigate the actual change.


PART 2: Understand History and Undo Mistakes Safely

6. git log --graph: See the Big Picture

A Git repository is not merely a list of commits. Branches can diverge, merge, and evolve independently.

The following command makes that history easier to understand:

git log --oneline --graph --all

Example output:

* a1b2c3d (HEAD -> main) Add payment feature
| * d4e5f6a (feature/login) Fix login issue
| * e7f8a9b Update API
|/
* 1234567 Initial commit

This gives you a compact view of commits, branch relationships, and merges.

Why do DevOps engineers need it?

When a deployment contains an unexpected change, you may need to establish:

  • Which commits are included in a release.

  • Whether a branch contains a particular fix.

  • Where two branches diverged.

  • Whether a merge brought in unrelated changes.

Useful variations

# Show recent commits
git log --oneline -10

# Include all branches
git log --oneline --all

# Show file-level changes for a commit
git show --stat <commit-hash>

Remember: A readable commit graph makes complicated branch history easier to investigate.

7. git reset: Undo Changes at Different Levels

git reset is useful, but the different modes matter.

Using the wrong mode can remove changes you intended to keep.

Soft reset

git reset --soft HEAD~1

Moves the current branch reference back one commit while keeping the undone commit’s changes staged.

Use this when you want to revise a recent commit without losing its staged changes.

Mixed reset

git reset HEAD~1

Mixed is the default mode.

It moves the branch reference back and resets the index, while keeping the working-tree changes.

The changes remain in your files but are no longer staged.

Hard reset

git reset --hard HEAD~1

Moves the branch reference back, resets the index, and updates tracked working-tree files to match the target commit.

Uncommitted changes can be lost. Do not use it casually.

Which mode should you use?

  • Soft: Keep changes staged.

  • Mixed: Keep changes in the working directory but unstaged.

  • Hard: Discard tracked working-tree changes that differ from the target state.

Production warning

If the commit has already been pushed and other developers may have based their work on it, rewriting shared history can disrupt collaboration.

For a published change that needs to be undone, git revert is often the safer choice because it creates a new commit that reverses the earlier change.

Remember: Before resetting, confirm which commit you are targeting and whether your work is safely preserved.

8. git rebase -i: Clean Up Your Commit History

During development, you may create commits such as:

Fix typo
Fix another typo
Update validation
Fix validation test
Final fix

These commits are understandable while working, but the final pull request may be easier to review if the history is organised.

Interactive rebase lets you reorder, edit, combine, or remove commits.

Start an interactive rebase over the last five commits:

git rebase -i HEAD~5

Git opens a todo list with entries such as:

pick 1111111 Add service
pick 2222222 Update validation
pick 3333333 Fix typo
pick 4444444 Fix lint
pick 5555555 Final version

You can change actions in the list. For example, squash combines a commit with the preceding commit while allowing you to edit the resulting commit message.

A typical cleaned-up history might represent the work as a single coherent feature commit rather than several small corrections.

Important warning

Interactive rebase rewrites commit history. Avoid rewriting commits that other people are already using unless the team has explicitly coordinated that change.

After resolving a rebase conflict, continue with:

git add <resolved-file>
git rebase --continue

To abandon the rebase:

git rebase --abort

Remember: Rebase is useful for organising private or coordinated branch history, not for silently rewriting shared work.


PART 3: Work in Parallel and Keep Repositories Clean

9. git worktree: Work on Multiple Branches at the Same Time

Imagine you are developing a feature and suddenly need to investigate a hotfix.

Normally, you might stash your changes, switch branches, perform the fix, and then switch back. That workflow is fine, but it becomes awkward when both tasks require separate build environments or lots of context.

Git worktrees allow multiple working directories to use the same repository.

Create a separate working directory

git worktree add ../hotfix hotfix/payment

This creates a working directory at ../hotfix using the existing hotfix/payment branch.

You can inspect registered worktrees with:

git worktree list

When you no longer need a worktree, remove it:

git worktree remove ../hotfix

Only remove a worktree after checking for uncommitted changes and confirming that you no longer need that directory.

Production scenario

You have a long-running feature in one directory. A production bug needs investigation in another branch.

With worktrees, you can keep the feature workspace intact while opening a separate workspace for the hotfix.

Both directories use the same underlying repository data, although each has its own working tree and index.

Important detail

A local branch normally cannot be checked out in multiple worktrees simultaneously. If the branch is already checked out elsewhere, create a different branch for the second workspace when appropriate.

Remember: Worktrees let you work on multiple branches without constantly switching one directory between them.

10. git clean: Remove Untracked Files Carefully

Build artifacts, temporary files, generated logs and other untracked files can accumulate in a repository.

git clean removes untracked files and directories, but it can be destructive if used without checking what will be removed.

Preview first

git clean -n

The -n option performs a dry run. It shows what would be removed without deleting it.

To include untracked directories in the preview:

git clean -nd

After reviewing the output, remove untracked files:

git clean -f

To remove untracked files and directories:

git clean -fd

Ignored files are not normally removed by these commands. Removing ignored files requires additional options, so avoid experimenting with them in a repository containing valuable local configuration or build data.

Why is this useful?

A clean working directory can help reproduce a build from a known state and identify which files are generated rather than version-controlled.

However, do not assume every untracked file is disposable. Developers often keep local scripts, test data or configuration files outside version control.

Remember: Preview before cleaning. Git cannot recover a file that was never committed just because you regret deleting it.


A Practical Git Troubleshooting Workflow

When a repository problem appears, use a consistent process instead of running commands at random.

Step 1: Inspect the current state

git status
git log --oneline --graph --all -15

Understand your current branch, staged changes and recent history.

Step 2: Protect valuable work

Before destructive operations, commit or otherwise preserve changes that you need.

For example:

git stash push -u -m "Backup before investigation"

Remember that a stash is not a complete backup of every possible repository file, especially ignored files.

Step 3: Identify the problem

Choose the command that matches the issue:

  • Lost commit: git reflog

  • Interrupted work: git stash

  • One missing fix: git cherry-pick

  • Unknown regression: git bisect

  • Unclear line history: git blame

  • Confusing branch relationships: git log --graph

  • Recent commit needs adjustment: git reset

  • Messy local history: git rebase -i

  • Need parallel workspaces: git worktree

  • Untracked clutter: git clean

Step 4: Verify the result

After making a change, check:

git status
git log --oneline --graph -10

Then run the relevant tests before pushing or deploying.

Final Thoughts 🎯

Mastering Git is not about memorising dozens of commands. It is about understanding how Git stores commits, tracks references, manages branches, and represents changes.

The commands in this guide become especially valuable when working under pressure:

  • git reflog can help recover a previous reference.

  • git stash can temporarily preserve unfinished changes.

  • git cherry-pick can apply an individual fix.

  • git bisect can narrow down the commit responsible for a regression.

  • git blame can trace the history of a line.

  • git log --graph can make branch history easier to understand.

  • git reset can adjust local history, but requires care.

  • git rebase -i can organise commits.

  • git worktree can support parallel work.

  • git clean can remove untracked clutter after a careful preview.

The most important skill is knowing not only which command to use, but also what that command will change and how to recover if the result is not what you expected.

In a real engineering environment, the best Git user is not the person who types the fastest. It is the person who can investigate a problem, protect valuable work, explain the trade-offs, and make a safe change.

Master the commands. Understand the consequences. Keep your repository history useful. Your future self, usually debugging something at an inconvenient hour, will appreciate it. 🛠️


Hashtags

#Git #GitCommands #GitAdvanced #GitHub #DevOps #SoftwareEngineering #VersionControl #CICD #PlatformEngineering #DeveloperTools #CloudEngineering #SRE #CodingTips #DevOpsEngineer

Follow Me

If you enjoyed this article and want more practical DevOps, Cloud, Kubernetes, AWS, Terraform, CI/CD, and Software Engineering content, connect with me on LinkedIn.

LinkedIn: https://www.linkedin.com/in/arvindverma021/

Arvind Verma is free today. But if you enjoyed this post, you can tell Arvind Verma that their writing is valuable by pledging a future subscription. You won't be charged unless they enable payments.

Pledge your support

© 2026 Arvind Verma
548 Market Street PMB 72296, San Francisco, CA 94104