1. You have edited three tracked files. What does this stage?
IntermediateAnswer: All three, plus any new untracked files in the current directory
`git add .` stages everything under the current directory, including untracked files — which is how secrets and build output end up committed. `git status` first, and a real `.gitignore`, are what keep it safe.
Official documentation →2. You have 3 uncommitted modified files. What happens?
Advancedbashgit reset --hard HEAD~1
Answer: The last commit is discarded AND all uncommitted changes are lost
`--hard` resets the branch pointer, the index and the working tree, so uncommitted work is destroyed with no reflog entry to recover it. `--soft` keeps everything staged and `--mixed` (the default) keeps it unstaged — both are recoverable.
Official documentation →3. You accidentally ran `git reset --hard` and lost a commit. What recovers it?
AdvancedAnswer: git reset --hard <sha> using the sha shown in the reflog
The reflog records every position HEAD has held, so a 'lost' commit is usually still reachable for around 90 days before garbage collection. This is the single most valuable recovery tool in Git — the commit was orphaned, not deleted.
Official documentation →4. What is the difference between these two?
Intermediatebashgit diff
git diff --staged
Answer: The first shows unstaged changes; the second shows what is staged
`git diff` compares the working tree against the index, so it shows what you have *not* staged. `--staged` (or `--cached`) compares the index against HEAD — what the next commit will contain. Reviewing the staged diff before committing catches a lot of mistakes.
Official documentation →5. You meant to create a branch and switch to it, but you are still on main. Which line is wrong?
Intermediatebash1 git branch feature/login
2 git status
3 # On branch main
Answer: Line 1 — git branch creates the branch but does not switch to it
`git branch <name>` only creates the pointer. Use `git switch -c <name>` (or the older `git checkout -b`) to create and move in one step. Slashes in branch names are fine and are the usual convention for grouping.
Official documentation →6. This wipes a teammate's commits from the shared branch. Which line is dangerous?
Advancedbash1 git checkout main
2 git pull
3 git rebase -i HEAD~5
4 git push --force
Answer: Line 4 — --force overwrites whatever the remote has, including new commits
`--force` replaces the remote branch unconditionally, discarding anything pushed since your last fetch. `--force-with-lease` refuses if the remote moved, which makes it the safe default. Rewriting a shared branch at all is the deeper problem.
Official documentation →7. Fill in the blank to discard your local changes to one file and restore it from the last commit.
IntermediateAnswer: restore
`git restore <path>` overwrites the working file from the index — destructive, with no reflog entry, so uncommitted edits are gone. `git revert` creates an undo commit, and `git clean` removes untracked files.
Official documentation →8. main has moved on since you branched. What does this do?
Intermediatebashgit switch feature
git merge main
Answer: Brings main's commits into feature, creating a merge commit if both diverged
Merging main *into* your feature branch updates it with the latest work while leaving main untouched. Doing this regularly keeps conflicts small. A merge commit appears only when both sides have new commits; otherwise it fast-forwards.
Official documentation →9. Your branch and main have both moved on. What does this produce?
Advancedbashgit checkout feature
git rebase main
Answer: Your commits are replayed on top of main, with new SHAs
Rebase re-applies each of your commits onto the new base, creating new commits with different SHAs — the originals are orphaned but remain in the reflog. That SHA change is exactly why rebasing a branch others have pulled causes problems.
Official documentation →10. What do the conflict markers mean?
Intermediatebash<<<<<<< HEAD
const timeout = 3000
=======
const timeout = 5000
>>>>>>> feature
Answer: Above ======= is your current branch; below is the incoming branch
HEAD is where you are; the label after `>>>>>>>` is what you are merging in. Resolving means editing the file to the version you want — including possibly neither — and deleting all three marker lines before staging it.
Official documentation →11. What does this show?
IntermediateAnswer: The last 5 commits, one line each
`-5` limits the count and `--oneline` condenses each commit to an abbreviated SHA and subject. `--graph` adds the branch topology, which is the quickest way to see how branches actually relate.
Official documentation →12. Your push is rejected as non-fast-forward. Which line explains why?
Intermediatebash1 git commit -m 'fix'
2 git push origin main
3 # ! [rejected] main -> main (fetch first)
Answer: Someone pushed to main since your last fetch, so your history is behind
The remote has commits you do not. `git pull` (or `fetch` then `merge`/`rebase`) reconciles them, then the push succeeds. Reaching for `--force` here would delete the other person's work.
Official documentation →13. What does this do?
Advancedbashgit cherry-pick abc123
Answer: Applies that single commit's changes as a new commit on the current branch
Cherry-pick copies one commit's diff onto the current branch as a new commit with a new SHA — the original stays put. It is the usual way to pull an urgent fix from a feature branch into a release branch without taking the rest of the work.
Official documentation →14. What is the difference?
Intermediatebashgit pull
git pull --rebase
Answer: The first may create a merge commit; the second replays your commits on top
Plain `pull` is fetch + merge, so diverged histories produce a merge commit. `--rebase` replays your local commits on top of the fetched ones, giving a linear history — at the cost of rewriting their SHAs, which is fine while they are unpushed.
Official documentation →15. Fill in the blank to save your uncommitted work temporarily and return to a clean tree.
Advancedbashgit ____
git checkout main
# later
git ____ pop
Answer: stash
`git stash` stores modified tracked files and reverts the tree; `pop` reapplies and drops the entry, while `apply` reapplies and keeps it. Note untracked files are ignored unless you pass `-u`, which surprises people who stash then wonder where their new file went.
Official documentation →16. What does this find?
Advancedbashgit bisect start
git bisect bad HEAD
git bisect good v1.0
Answer: The first commit that introduced a bug, via binary search
Bisect binary-searches the range, checking out a midpoint for you to test and mark good or bad. It finds the culprit among 1,000 commits in about 10 steps. `git bisect run ./test.sh` automates it entirely when you have a script that exits non-zero on failure.
Official documentation →17. Fill in the blank to unstage a file you added by mistake, keeping your edits.
Intermediatebashgit restore --____ secrets.env
Answer: staged
`--staged` touches only the index, so the file leaves the staging area but your working copy is untouched. Without the flag, `git restore` overwrites the working file instead — the destructive direction.
Official documentation →18. A colleague reports your merged feature is missing changes. Which line explains it?
Advancedbash1 git checkout feature
2 git merge main
3 # resolved conflicts by keeping only main's side
4 git commit
5 git checkout main && git merge feature
Answer: Line 3 — discarding your side during conflict resolution silently drops your work
Resolving a conflict by taking one side wholesale is a real code change, and Git records it as intentional — the later merge sees nothing left to bring across. Conflict resolutions deserve the same review as any other change; `git diff` after resolving is worth the ten seconds.
Official documentation →19. What happens to your uncommitted work?
Intermediatebashgit stash
git switch main
Answer: Modified tracked files are saved and the tree is clean; untracked files stay put
`git stash` saves modifications to tracked files only. New untracked files are left in the working tree unless you pass `-u`, which surprises people who stash, switch branches, and find their new file followed them across.
Official documentation →20. What is the difference in the resulting history?
Advancedbashgit merge --squash feature
git commit -m 'Add feature'
Answer: All the branch's commits become one new commit, with no merge commit
Squash-merge collapses the branch's work into a single commit on the target, discarding the intermediate history and the merge link. It keeps main readable at the cost of losing granular history — which is why many teams squash feature branches but never squash release merges.
Official documentation →21. What does this do?
Intermediatebashgit commit --amend --no-edit
Answer: Folds the staged changes into the previous commit, keeping its message
Useful for the file you forgot to stage a second ago. It replaces the commit rather than editing it, so the SHA changes — fine locally, but it means a push is refused if the original was already shared.
Official documentation →22. What does this delete?
Intermediatebashgit branch -d feature/login
Answer: The local branch pointer, but only if it is already merged
Lowercase `-d` refuses to delete an unmerged branch, which is a useful guard; `-D` forces it. Either way only the local pointer goes — the remote branch needs `git push origin --delete feature/login`, and the commits survive in the reflog for a while.
Official documentation →23. A build artifact keeps appearing in every diff even though it is in .gitignore. Which line explains it?
Intermediatebash1 echo 'dist/' >> .gitignore
2 git status
3 # modified: dist/bundle.js
Answer: The file was already tracked; .gitignore only affects untracked files
Once a file is tracked, Git keeps tracking it regardless of ignore rules. `git rm --cached dist/bundle.js` stops tracking it while leaving it on disk; commit that removal and the ignore rule takes over.
Official documentation →24. Fill in the blank to force-push safely, refusing if the remote has moved.
Advancedbashgit push --force-with-____ origin feature
Answer: lease
`--force-with-lease` compares the remote against what you last fetched and aborts if someone else has pushed, so you cannot silently discard their work. It is strictly better than `--force` and worth aliasing as your default.
Official documentation →