Backend / Git / 01_git_commands.md

Git: the commands that get asked about

Updated 6 interview angles 3 min read source
On this page6
  1. The three trees
  2. Undoing something already pushed
  3. Merge or rebase
  4. Recovering from a mistake
  5. Finding the commit that broke it
  6. Interview angle

Git: the commands that get asked about

Nobody is tested on git add. What gets probed is the handful of operations where getting it wrong costs someone else their afternoon: rewriting shared history, undoing a pushed commit, and recovering from either.

The three trees

Almost every confusing Git answer becomes obvious once this is explicit:

text
working tree  ──add──▶  index (staging)  ──commit──▶  HEAD

reset moves HEAD and optionally the other two, which is the entire difference between its flags:

bash
git reset --soft  HEAD~1   # undo commit, keep it staged
git reset --mixed HEAD~1   # keep changes unstaged (default)
git reset --hard  HEAD~1   # undo commit, discard the work

--soft is the “I want to redo that commit message or split it” move. --hard is the only one that destroys work, and it is why the next section exists.

Undoing something already pushed

bash
git revert <sha>      # new commit that reverses <sha>

Not reset --hard then force-push. Revert adds history; reset rewrites it, and rewriting history someone else has pulled means their next pull produces a merge between two versions of the same work. The recovery is manual and it is their problem, not yours.

Situation Use
Pushed, others may have it revert
Local only, not pushed reset
Pushed to your own branch, no reviewers push --force-with-lease

--force-with-lease rather than --force: it refuses if the remote moved since you last fetched, so you cannot silently overwrite a colleague’s push.

Merge or rebase

bash
git switch feature
# replay my commits on top of main
git rebase main

Rebase gives a linear history and makes git log readable. It also rewrites every commit it touches — new SHAs — so the rule is: rebase your own unpublished branch, merge anything shared.

Gotcha: “never rebase a branch others have pulled” is the rule people recite and then break with git pull --rebase on a shared branch. Rebasing during a pull rewrites your local commits, which is fine, but if you had already pushed them it produces duplicates on the next push.

Recovering from a mistake

bash
git reflog
# 8a3c1f2 HEAD@{0}: reset: moving to HEAD~3
# 4f7b9e1 HEAD@{1}: commit: the work you thought was gone

git reset --hard 4f7b9e1

reflog records every position HEAD has held locally, whether or not those commits are reachable from any branch. A botched reset, a deleted branch, a rebase that went wrong — all recoverable, typically for 90 days.

This is the single most valuable Git answer, because the honest version of “have you ever lost work in Git” is “no, because of reflog”.

Finding the commit that broke it

bash
git bisect start
git bisect bad                 # current commit is broken
git bisect good v2.3.0         # this tag was fine
# git checks out the midpoint; test, then:
git bisect good   # or: git bisect bad

Binary search over history — ten steps across a thousand commits. With a test script it runs unattended:

bash
git bisect run pytest tests/test_regression.py

Interview angle 6

  • “Merge or rebase?” - rebase your own unpublished branch to keep history linear before merging; merge anything shared. Rebasing rewrites commits, so doing it to a branch others have pulled forces everyone to recover by hand.
  • “How do you undo a commit that’s already pushed?” - git revert, which adds a commit reversing the change and preserves shared history. reset --hard plus a force-push rewrites history and is only safe on a branch nobody else has.
  • “What’s the difference between the reset modes?” - all three move HEAD. --soft leaves the changes staged, --mixed leaves them in the working tree, --hard discards them. Only --hard loses work.
  • “How do you recover something you think you destroyed?” - git reflog. It records every position HEAD has held locally, so a botched reset, a deleted branch or a bad rebase is usually recoverable for around 90 days.
  • “Why --force-with-lease rather than --force?” - it refuses the push if the remote moved since your last fetch, so you cannot overwrite a colleague’s commit without noticing. Plain --force will happily discard it.
  • “A regression appeared somewhere in the last 200 commits. Find it.” - git bisect, which binary-searches history in about eight steps. With git bisect run <test-command> it finds the commit unattended.