Test what you actually know about Git. Free sample questions below, from easy to hard, with instant explanations.
git add doesn't save anything permanently yet, it just marks changes as 'include this in the next commit' by moving them into the staging area. The actual permanent save happens with git commit.
--soft is the gentlest form of undo: it moves HEAD back one commit, but it doesn't touch your actual files, and it leaves that commit's changes sitting in the staging area, ready for you to re-commit (maybe combined with something else) rather than losing them.
Interactive rebase lets you mark any past commit as `edit`, which pauses the rebase with that commit checked out so you can amend it, then `git rebase --continue` replays the remaining commits on top of your fix, each keeping its own identity, though with new SHAs since their parent changed. Plain `git commit --amend` only ever touches the single most recent commit, HEAD, it has no way to target an older commit directly.
`git log --author` filters the commit list down to those whose author field matches the given pattern. `--grep` searches commit messages instead of author identity, and `git blame` shows per-line authorship for a single file rather than filtering the log.
The `pre-push` hook runs locally right before a push actually sends data to the remote, and if the script exits non-zero, Git aborts the push, making it the right place for a local test-suite gate. `pre-receive` is a server-side hook that runs on the remote when it receives a push, it isn't something you configure locally, and `post-commit`/`commit-msg` run at commit time, before a push is even happening.
`git bisect run` takes a script or command, checks out each bisection candidate automatically, runs it, and uses the exit code to decide the next step: 0 means good, any code from 1 to 124 means bad, and the special code 125 means "can't test this commit, skip it." This turns what would be manual back-and-forth into a single unattended command that finishes with the exact first-bad commit already identified.
The pre-commit hook runs right before Git finalizes a commit, letting a script inspect the staged content and abort the commit, by exiting non-zero, if something's wrong, such as a failing linter. A post-merge hook only fires after a merge has already completed, so it can't block anything, and an alias is just a shortcut for typing commands, not an enforcement mechanism.
git blame goes line by line through a file and tells you exactly which commit (and which author) last touched each one, which is exactly what you want when you're trying to figure out who wrote a weird line of code and why.
Rewriting history creates new commits with new SHAs, but the old commits and the blob they reference aren't actually gone until nothing still references them: leftover refs and stale reflog entries keep them reachable, so a full cleanup needs those cleared plus `git gc --prune=now` to actually delete now-unreachable objects. Even then, that's only true locally, since anyone else's clone or fork of the repo still holds the old, unrewritten history in full until they re-clone or perform the same rewrite and force-push, which is exactly why history rewrites are so disruptive for shared repositories.
Think of the staging area as a holding pen between your files and your commit history: git add moves changes there, and only what's actually in that holding pen is what git commit will save, which is why you can choose to commit some changes but not others.
Real scenario-based DevOps questions, hands-on practice, and clear explanations for every answer.