interviewDeck

Your one-stop platform to prepare, practice and ace your interviews.

Loading your questions…

All Questions

Filters & tools

Git Interview Questions and Answers

28 hand-picked Git interview questions with detailed answers. Open the interactive version above to search, filter by difficulty, run code, bookmark questions and track your progress.

Merge vs rebase.

Merge combines branches with a merge commit — preserves the true history, non-destructive.

Rebase replays your commits on top of another branch — a linear, clean history, but rewrites commits. Never rebase branches others have pulled.

git rebase main   # replay feature commits onto main

git fetch vs git pull.

fetch downloads remote changes but doesn't touch your working branch — you can inspect first. pull = fetch + merge (or rebase) into your current branch in one step.

reset vs revert vs checkout.

  • revert — creates a new commit that undoes a previous one; safe on shared branches.
  • reset — moves the branch pointer (soft/mixed/hard); rewrites history, use locally.
  • checkout / switch / restore — move between branches or restore files.
git revert <hash>   # safe undo
git reset --hard HEAD~1  # local-only

What does git stash do?

Temporarily shelves uncommitted changes so you can switch context (e.g. fix an urgent bug on another branch), then reapply them with git stash pop.

git stash
git switch main
# ... later ...
git switch feature && git stash pop

What is git cherry-pick?

Applies a single specific commit from one branch onto another — useful for hotfixes you need on multiple branches without merging everything.

git cherry-pick <hash>

Describe a common branching strategy.

GitFlow — long-lived main and develop, plus feature/*, release/*, and hotfix/* branches. Simpler alternative: trunk-based / GitHub Flow — short-lived feature branches merged to main via pull requests.

How do you resolve a merge conflict?

Git marks conflicting regions with <<<<<<< / ======= / >>>>>>>. Edit to the desired result, remove the markers, git add the files, then commit (or git rebase --continue).

How do you recover a 'lost' commit?

git reflog logs where HEAD has been, including commits orphaned by a reset/rebase. Find the hash and git checkout or git reset back to it.

git reflog
git reset --hard <hash>

What is squashing and why do it?

Combining several commits into one (via interactive rebase or a squash-merge) to keep the main branch history clean — one logical change = one commit.

git rebase -i HEAD~3   # mark commits as 'squash'

What is HEAD and a detached HEAD?

HEAD points to your current commit/branch. A detached HEAD means you've checked out a specific commit rather than a branch — new commits there aren't on any branch and can be lost unless you create one.

git switch -c new-branch  # save detached-HEAD work

What do you look for in a code review? Describe your PR process.

A layered checklist, most important first:

  • Correctness — does it do what the ticket says; edge cases (null/empty/concurrent); error handling.
  • Design — right layer for the logic, no duplication of existing utilities, sane API shapes, backward compatibility.
  • Safety — SQL injection/XSS, secrets in code, N+1 queries, missing indexes on new queries, transaction boundaries.
  • Tests — meaningful cases (not just coverage), failure paths tested.
  • Readability last — naming, dead code; style nits belong to the linter, not humans.

Process: small PRs (< ~400 lines review well), a description that says why, CI green before human eyes, comments phrased as questions, and approval means I'd maintain this.

Working directory, staging area, and repository.

Git has three 'trees':

  • Working directory — the actual files you edit.
  • Staging area (index) — a snapshot you're preparing; git add moves changes here.
  • Repository — committed history; git commit records the staged snapshot permanently.

The staging area is what lets you commit only some of your changes.

git add file.js      # working dir -> staging
git commit -m "msg"  # staging -> repository

clone vs fork.

clone — a Git operation that makes a local copy of a repository (with full history) that you can pull from and, with access, push to.

fork — a hosting-platform (GitHub/GitLab) concept: a server-side copy of a repo under your account. You fork a project you can't push to, clone your fork, then open a pull request back to the original.

git clone https://github.com/user/repo.git

.gitignore — how it works and the common mistakes.

.gitignore lists path patterns Git should not track (build output, node_modules, secrets). It only affects untracked files.

Gotcha: a file already tracked keeps being tracked even after you add it to .gitignore — you must untrack it explicitly.

git rm --cached .env      # stop tracking, keep the file
echo ".env" >> .gitignore

Inspecting history: log, diff, and show.

  • git log — commit history; --oneline --graph for a compact branch view.
  • git diff — unstaged changes; --staged for what's about to commit; A..B to compare commits/branches.
  • git show <commit> — the full patch and metadata of one commit.
git log --oneline --graph --all
git diff --staged
git show HEAD~2

Git tags — lightweight vs annotated.

A tag is a named pointer to a specific commit, typically marking a release.

  • Lightweight — just a name → commit pointer.
  • Annotated (-a) — a full object storing tagger, date, message, and can be signed. Recommended for releases.

Tags aren't pushed by default — you must push them explicitly.

git tag -a v1.2.0 -m "Release 1.2.0"
git push origin v1.2.0

What does git commit --amend do?

It replaces the most recent commit with a new one — letting you fix the commit message or fold in additional staged changes you forgot. Technically it creates a brand-new commit (new hash) and moves the branch to it.

git add forgotten.js
git commit --amend --no-edit   # fold in, keep message

Interactive rebase — what can it do?

git rebase -i opens an editable list of commits so you can rewrite a series before merging:

  • reword — change a message
  • squash / fixup — combine commits (fixup discards the message)
  • edit — stop to amend a specific commit
  • reorder / drop — rearrange or delete commits
git rebase -i HEAD~4   # curate the last 4 commits

Fast-forward vs no-ff merge.

A fast-forward merge happens when the target branch hasn't diverged — Git just moves the branch pointer forward, no merge commit, a perfectly linear history.

--no-ff forces a merge commit even when a fast-forward is possible, preserving the fact that a feature branch existed as a distinct group of commits.

git merge --no-ff feature   # always create a merge commit

git pull --rebase vs a plain pull.

A default git pull does fetch + merge, which can litter history with 'Merge branch main' commits when you and the remote both moved.

git pull --rebase instead replays your local commits on top of the fetched remote — a clean, linear history with no extra merge commits.

git pull --rebase origin main

How does git bisect find a bug?

A binary search through history for the commit that introduced a bug. You mark a known-bad commit and a known-good one; Git checks out the midpoint, you test and mark it good/bad, and it halves the range each step until it pinpoints the culprit.

git bisect start
git bisect bad            # current is broken
git bisect good v1.0     # this tag worked
# test each checkout, then:  git bisect good|bad
git bisect reset

What is git blame for?

git blame annotates each line of a file with the commit, author, and date that last changed it — the way to find when and why a specific line came to be, then read that commit's message/PR for context.

git blame -L 40,60 src/app.js   # who touched lines 40-60

What are Git hooks?

Scripts Git runs automatically on events: pre-commit (lint/format), commit-msg (enforce message format), pre-push (run tests), post-merge, etc.

They live in .git/hooks and are not committed — so teams use tools like Husky or pre-commit to share and version them.

# .husky/pre-commit
npm run lint && npm test

reset --soft vs --mixed vs --hard.

All three move HEAD to a target commit; they differ in what else they touch:

  • --soft — moves HEAD only; changes stay staged.
  • --mixed (default) — moves HEAD and unstages; changes remain in the working directory.
  • --hard — moves HEAD and discards both staged and working changes.
git reset --soft HEAD~1   # undo last commit, keep changes staged
git reset --hard HEAD~1   # undo last commit, throw changes away

What are Git submodules?

A submodule embeds one repository inside another, pinned to a specific commit of the child. The parent tracks only that pointer, not the child's files.

Pros: share a library across projects with exact version control. Cons: extra ceremony — clones need --recurse-submodules, and it's easy to forget to commit an updated pointer.

git clone --recurse-submodules <url>
git submodule update --init --recursive

How do you remove a secret or large file from all of history?

Deleting it in a new commit isn't enough — it's still in every prior commit. Use git filter-repo (the modern replacement for filter-branch, or the BFG tool) to rewrite every commit and purge the file/string.

This changes all commit hashes, so you must force-push and everyone must re-clone — and you should rotate the leaked secret regardless, since it may already be cloned.

git filter-repo --path secrets.env --invert-paths
git push --force --all

What is git worktree?

git worktree checks out multiple branches into separate directories backed by a single repository (shared .git). You can work on an urgent hotfix in one folder without stashing or disturbing your half-done feature in another.

git worktree add ../hotfix main
# fix, commit, then:
git worktree remove ../hotfix

Explain Git's object model.

Git is a content-addressable store of four object types, each keyed by a hash of its content:

  • blob — file contents.
  • tree — a directory listing (names → blobs/trees).
  • commit — a snapshot: root tree + parent commit(s) + author/message.
  • tag — an annotated pointer to a commit.

Refs (branches) are just movable pointers to commit hashes.

git cat-file -t HEAD    # commit
git cat-file -p HEAD    # inspect the object graph