FroquizFroquiz
HomeQuizzesSenior ChallengeGet CertifiedBlogAbout
Sign InStart Quiz
Sign InStart Quiz
Froquiz

The most comprehensive quiz platform for software engineers. Test yourself with 10000+ questions and advance your career.

LinkedIn

Platform

  • Start Quizzes
  • Topics
  • Blog
  • My Profile
  • Sign In

About

  • About Us
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

Β© 2026 Froquiz. All rights reserved.Built with passion for technology
Blog & Articles

Git Advanced Techniques: Rebase, Cherry-Pick, Bisect, Hooks and Workflows

Go beyond basic Git. Learn interactive rebase, cherry-pick, git bisect for debugging, reflog recovery, hooks for automation, and professional branching workflows.

Yusuf SeyitoğluMarch 17, 20260 views10 min read

Git Advanced Techniques: Rebase, Cherry-Pick, Bisect, Hooks and Workflows

Most developers use Git for add, commit, push, and pull. But Git's advanced features are what separate developers who work efficiently in teams from those who create messy histories and struggle with conflicts. This guide covers the techniques that appear in senior developer interviews and save hours in real projects.

Interactive Rebase

Interactive rebase is one of the most powerful Git tools. It lets you rewrite history before merging β€” squash commits, reword messages, reorder, split, or drop commits entirely.

bash
-- Rewrite the last 4 commits interactively git rebase -i HEAD~4 -- Rebase onto main (rewrite all commits not in main) git rebase -i main

This opens your editor with a list like:

code
pick a1b2c3 Add user authentication pick d4e5f6 Fix typo in comment pick 7g8h9i Add tests for auth pick j0k1l2 WIP: debugging session -- Commands: -- p, pick = use commit as-is -- r, reword = use commit, but edit the message -- e, edit = use commit, but stop for amending -- s, squash = meld into previous commit -- f, fixup = like squash, but discard this commit's message -- d, drop = remove commit

Change to:

code
pick a1b2c3 Add user authentication f d4e5f6 Fix typo in comment s 7g8h9i Add tests for auth d j0k1l2 WIP: debugging session

Result: one clean commit combining auth + tests, typo fix merged silently, WIP removed entirely.

Never rebase commits that have been pushed to a shared branch. Rebase rewrites history β€” it changes commit SHAs.

git rebase vs git merge

bash
-- Merge: creates a merge commit, preserves history git checkout feature git merge main -- History: A -- B -- C (main) -- \ \ -- D -- E -- M (merge commit) -- Rebase: replays commits on top of main, linear history git checkout feature git rebase main -- History: A -- B -- C -- D' -- E' (linear)

Use merge for integrating long-lived branches (releases, hotfixes) β€” preserves context. Use rebase for keeping feature branches up to date with main β€” linear, readable history.

Cherry-Pick

Apply a specific commit from another branch to your current branch:

bash
-- Apply a single commit git cherry-pick a1b2c3 -- Apply a range of commits git cherry-pick a1b2c3..d4e5f6 -- Cherry-pick without committing (stage only) git cherry-pick --no-commit a1b2c3 -- Cherry-pick and edit the message git cherry-pick --edit a1b2c3

Use cases:

  • Backport a bug fix to a release branch without merging the entire feature
  • Apply a specific commit from an abandoned branch
  • Move commits accidentally made on the wrong branch
bash
-- Accidentally committed to main instead of feature branch git log --oneline -- abc123 My new feature -- Create feature branch pointing to the commit before your mistake git checkout -b feature-branch HEAD~1 -- Cherry-pick the commit onto the new branch git cherry-pick abc123 -- Remove from main (reset, keeping changes staged) git checkout main git reset HEAD~1

git bisect

Binary search through commit history to find exactly which commit introduced a bug:

bash
-- Start bisect session git bisect start -- Tell Git the current commit is bad (has the bug) git bisect bad -- Tell Git a known good commit (before the bug existed) git bisect good v2.0.0 -- Git checks out the midpoint commit -- Test your application, then tell Git: git bisect good -- or git bisect bad -- Git keeps halving the range until it finds the exact commit -- "a1b2c3 is the first bad commit" -- When done git bisect reset -- return to original HEAD

Automate with a test script:

bash
-- Git runs your script on each commit -- exit 0 = good, exit 1 = bad git bisect run npm test -- --grep "the failing test"

bisect finds the culprit commit in O(log n) steps β€” for 1000 commits, only 10 checks.

The Reflog: Your Safety Net

git reflog records every time HEAD moves β€” commits, checkouts, rebases, resets. It is your recovery tool when things go wrong.

bash
git reflog -- a1b2c3 HEAD@{0}: rebase: finishing -- d4e5f6 HEAD@{1}: rebase: Add feature -- 7g8h9i HEAD@{2}: checkout: moving from main to feature -- j0k1l2 HEAD@{3}: commit: Oops, wrong branch -- Recover a commit you accidentally reset away git reset --hard HEAD@{3} -- Recover a deleted branch git checkout -b recovered-branch HEAD@{5} -- The reflog keeps entries for 90 days by default

Rule: Almost nothing in Git is truly lost as long as you committed it. The reflog can recover it.

git stash

Temporarily shelve changes without committing:

bash
git stash -- stash all tracked changes git stash push -m "WIP: auth" -- stash with a message git stash push -- src/auth.js -- stash specific file git stash -u -- include untracked files git stash list -- see all stashes git stash pop -- apply most recent, remove from stash git stash apply stash@{2} -- apply specific stash, keep it git stash drop stash@{1} -- delete a stash git stash branch feature-branch -- create branch from stash

Git Hooks

Hooks are scripts that run automatically at specific points in the Git workflow. They live in .git/hooks/ or can be managed with tools like Husky.

bash
-- .git/hooks/pre-commit (runs before every commit) #!/bin/bash set -e echo "Running linter..." npm run lint echo "Running tests..." npm test -- --passWithNoTests echo "Checking for console.log..." if git diff --cached | grep -q "console\.log"; then echo "Error: console.log found in staged changes" exit 1 fi
bash
-- .git/hooks/commit-msg (validates commit message format) #!/bin/bash COMMIT_MSG=$(cat "$1") PATTERN="^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: .{1,72}$" if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then echo "Bad commit message. Use: type(scope): description" echo "Example: feat(auth): add JWT refresh token support" exit 1 fi

Husky (shareable hooks for teams)

bash
npm install --save-dev husky lint-staged npx husky init
json
-- package.json { "lint-staged": { "*.{ts,tsx}": ["eslint --fix", "prettier --write"], "*.{css,md}": "prettier --write" } }
bash
-- .husky/pre-commit npx lint-staged

Professional Branching Workflows

GitHub Flow (simple, continuous deployment)

code
main β”œβ”€β”€ feature/user-auth β”œβ”€β”€ feature/payment-redesign └── fix/login-redirect
  1. Create branch from main
  2. Commit and push
  3. Open Pull Request
  4. Review and merge to main
  5. Deploy main

Clean, simple, works well for most teams.

Git Flow (release-based)

code
main (production releases only) develop (integration branch) β”œβ”€β”€ feature/xxx (branch from develop) β”œβ”€β”€ release/1.2.0 (branch from develop, merge to main + develop) └── hotfix/critical-bug (branch from main, merge to main + develop)

More structure β€” useful for products with scheduled releases, multiple maintained versions.

Useful Commands Worth Knowing

bash
-- Find which branch contains a commit git branch --contains a1b2c3 -- Show commits in branch-a not in branch-b git log branch-b..branch-a --oneline -- Find all commits that touched a file git log --follow -- src/auth/login.ts -- Show who last changed each line (blame) git blame src/auth/login.ts git blame -L 50,80 src/auth/login.ts -- lines 50-80 only -- Undo last commit, keep changes staged git reset --soft HEAD~1 -- Undo last commit, keep changes unstaged git reset HEAD~1 -- Undo last commit, discard changes git reset --hard HEAD~1 -- Fix last commit message (before pushing) git commit --amend -m "Better message" -- Add forgotten file to last commit git add forgotten.ts git commit --amend --no-edit

Common Interview Questions

Q: What is the difference between git merge and git rebase?

Both integrate changes from one branch into another. merge creates a merge commit that preserves the full history of both branches β€” non-destructive. rebase moves commits to a new base, creating new commit SHAs β€” results in a linear history but rewrites history. Never rebase shared branches.

Q: What is the difference between git reset and git revert?

reset moves the branch pointer backward β€” it rewrites history and should not be used on pushed commits (dangerous on shared branches). revert creates a new commit that undoes a previous commit β€” it is safe for shared branches because it adds to history rather than rewriting it.

Q: How would you recover a branch you accidentally deleted?

Use git reflog to find the commit SHA that the branch pointed to, then git checkout -b recovered-branch <sha>. The reflog keeps references for 90 days.

Practice on Froquiz

Git proficiency is tested in developer interviews at all levels. Explore our developer tool quizzes on Froquiz and check back as we add Git-specific content.

Summary

  • Interactive rebase (-i) lets you squash, reorder, reword, and drop commits before merging
  • Rebase creates linear history; merge preserves full history β€” use each deliberately
  • Cherry-pick applies specific commits across branches β€” great for backporting fixes
  • git bisect binary-searches commit history to find which commit introduced a bug
  • git reflog is your safety net β€” almost nothing committed is truly lost
  • Hooks automate code quality checks β€” use Husky to share them across the team
  • GitHub Flow (branch β†’ PR β†’ merge β†’ deploy) works for most teams

About Author

Yusuf Seyitoğlu

Author β†’

Other Posts

  • Modern JavaScript: ES2020 to ES2024 Features You Should Be UsingMar 17
  • Software Architecture Patterns: MVC, Clean Architecture, Hexagonal and Event-DrivenMar 17
  • PostgreSQL Full-Text Search: tsvector, tsquery, Ranking and Multilingual SearchMar 17
All Blogs