These Git interview questions cover what DevOps, cloud, platform and developer interviews in 2026 actually test: how Git stores history, how to branch, merge and rebase without hurting your team, and how to recover when something goes wrong on a shared repository. Interviewers rarely stop at "what is git pull"; they ask you to explain reset versus revert, recover a deleted branch from the reflog, or clean a leaked secret out of history, and they watch whether you reach for the safe command first. The 55 questions below run from fundamentals and internals to GitHub pull requests, rulesets, Actions, security, AI-assisted review and eleven real-world scenarios.
How to use this guide:
- Freshers and juniors are usually tested on the fundamentals: the three areas (working tree, staging area, repository), branching, fetch versus pull, .gitignore and tags. Be able to type the basic commands without looking them up.
- Mid-level developers and DevOps engineers get the merge versus rebase, reset versus revert, cherry-pick, stash, conflict and pull request questions, plus at least one recovery scenario.
- Senior and platform roles are pushed on internals, branching strategy, protected branches and rulesets, signed commits, monorepos, Git LFS, history rewriting and GitHub Actions security.
- Every command in this guide was run in a throwaway repository before publishing. Do the same: build a scratch repo, break it, and fix it. Saying "I tried this and the reflog showed..." lands far better than a memorised definition.
Contents
- Git fundamentals (Q1โQ11)
- Git internals: objects, refs and HEAD (Q12โQ15)
- Branching, merging, rebasing and undoing (Q16โQ26)
- GitHub interview questions: collaboration and governance (Q27โQ35)
- Advanced Git: hooks, monorepos, LFS and history rewriting (Q36โQ41)
- AI in Git workflows (Q42โQ44)
- Real-world scenario questions (Q45โQ55)
- Key takeaways
- Interview preparation checklist
- FAQ
Git fundamentals
1. What is Git, and what problem does version control solve?
Answer: Git is a distributed version control system: it records snapshots of a project over time so a team can see who changed what and why, work in parallel on branches, and return to any earlier state. Version control solves three problems: history (an auditable record of every change), collaboration (many people editing the same codebase without overwriting each other) and safety (you can always get back to a known-good version). Git's main features are cheap local branching, fast local operations because the whole history lives on your machine, content-addressed storage that makes corruption detectable, and a staging area that lets you craft commits deliberately.
Interview tip: "Distributed" is the word to explain. Every clone is a full repository with complete history, so you can commit, branch, diff and log offline. The remote on GitHub is a convention for sharing, not a technical requirement.
2. What is the difference between Git and GitHub?
Answer: Git is the open-source version control tool that runs on your machine. GitHub is a hosting platform built around Git repositories that adds collaboration and governance: pull requests, code review, issues, permissions, branch protection and rulesets, GitHub Actions for CI/CD, and security features such as dependency alerts and secret scanning. GitLab, Bitbucket and Azure Repos are alternatives that host Git repositories with their own review, CI and permission models. You can use Git with no hosting platform at all; you cannot meaningfully use GitHub without Git.
3. Explain the Git workflow: working directory, staging area and repository.
Answer: Git has three local areas. The working tree is the files you edit. The staging area (the index) holds the exact snapshot that the next commit will contain. The repository (the .git directory) stores committed history. Changes flow working tree โ git add โ index โ git commit โ repository, and then git push sends commits to a remote. In the other direction, git fetch downloads remote commits and git merge or git rebase integrates them.
working tree --add--> index --commit--> local repo
^ | ^
| push fetch
+---- checkout / restore v |
remote (origin)
4. What are the basic Git commands every engineer should know?
Answer: git init and git clone create a repository; git status shows what changed; git add stages; git commit -m records a snapshot; git log --oneline --graph shows history; git diff and git diff --staged show unstaged and staged changes; git switch and git branch manage branches; git fetch, git pull and git push sync with remotes; git restore discards working-tree changes and git restore --staged unstages. git switch and git restore were introduced to split the overloaded git checkout into clearer commands; checkout still works and you will see it in older scripts.
Interview tip: In a Git commands interview round, the follow-up is usually "what does that flag change?" Know --staged, -u, --oneline, --graph and -p, not just the bare commands.
5. What is the difference between a local and a remote repository, and how do you link them?
Answer: A local repository is the clone on your machine; a remote is another copy (usually on GitHub) that you exchange commits with. A remote is just a named URL, conventionally origin. To link an existing local project: git remote add origin <url>, then git push -u origin main. The -u flag sets the upstream so later plain git push and git pull know which remote branch to use. Remote-tracking branches such as origin/main are your local, read-only record of where the remote branch was at your last fetch.
6. What is the staging area, and why does it exist?
Answer: The staging area lets you choose exactly what goes into the next commit, independently of what is in your working tree. That makes it possible to split a messy afternoon of edits into small, logical commits: git add -p walks through each hunk and asks whether to stage it. Clean, focused commits make review easier, make git revert and git bisect precise, and make history readable. git diff --staged shows what you are about to commit; checking it before every commit is a habit interviewers like to hear about.
7. What is the difference between cloning and forking?
Answer: Cloning is a Git operation: git clone copies a repository, with full history, to your machine. Forking is a hosting-platform feature: it creates a server-side copy of someone else's repository under your own account. You fork when you cannot push to the original, which is the normal open-source flow: fork, clone your fork, add the original as a second remote (git remote add upstream <url>), work on a branch, push to your fork and open a pull request back to the original. Inside a company, engineers usually have write access and use branches in the same repository instead of forks.
8. How do you create and switch branches?
Answer: git branch feature-x creates a branch at the current commit without switching. git switch -c feature-x (or the older git checkout -b feature-x) creates and switches in one step. git switch main moves back. A branch is only a movable pointer to a commit, so creating one is instant regardless of repository size. git branch -d deletes a merged branch; -D forces deletion of an unmerged one (and Q45 shows how to get it back). git push origin --delete feature-x removes the remote branch.
9. What is the difference between git fetch and git pull?
Answer: git fetch downloads new commits and updates remote-tracking branches such as origin/main, but does not touch your working tree or current branch. git pull is fetch followed by an integration step: a merge by default, or a rebase if you pass --rebase or set pull.rebase true. Fetching first lets you inspect what changed (git log main..origin/main) before deciding how to integrate. Many teams set pull.ff only so a pull never silently creates a merge commit; if a fast-forward is not possible, you decide explicitly.
10. What is the purpose of .gitignore, and what if a file is already tracked?
Answer: .gitignore lists patterns for files Git should not track: build output, dependency folders, IDE settings, local environment files. It only affects untracked files. If a file is already committed, adding it to .gitignore does nothing; you must stop tracking it with git rm --cached <file> and commit, which removes it from future commits but not from history. That last point matters for secrets: if a .env file with credentials was committed, ignoring it now does not remove it from earlier commits (see Q47). Personal ignores that should not be shared go in .git/info/exclude or a global excludes file.
11. What are tags, and how do lightweight and annotated tags differ?
Answer: A tag is a named pointer to a specific commit, used to mark releases such as v1.4.0. A lightweight tag (git tag v1.4.0) is just a ref to the commit. An annotated tag (git tag -a v1.4.0 -m "Release 1.4.0") is a full Git object with tagger, date and message, and can be signed. Use annotated tags for releases. Tags are not pushed by default: git push origin v1.4.0 pushes one, git push origin --tags pushes all. Unlike branches, tags should never move; re-pointing a published release tag confuses every consumer and every cache. GitHub Releases are built on top of tags and add release notes and assets.
Interview tip: git cat-file -t v1.4.0 prints tag for an annotated tag and commit for a lightweight one. That is a neat way to show you understand tags are objects or refs.
Git internals: objects, refs and HEAD
12. What are Git objects, and how does Git store data?
Answer: Git is a content-addressed object store. There are four object types. A blob stores file contents (no filename). A tree maps names and modes to blobs and sub-trees, like a directory listing. A commit points to one top-level tree, zero or more parent commits, and records author, committer and message. An annotated tag points to an object with a message and tagger. Each object's ID is a hash of its contents (SHA-1 by default; Git also supports SHA-256 repositories). Because a commit's hash covers its tree and its parents, changing anything in history changes every descendant hash, which is why rewriting history forces collaborators to re-sync.
Real-world example: git cat-file -p HEAD prints the commit (its tree, parent, author and message); git cat-file -p 'HEAD^{tree}' lists the blobs and trees it points to. Walking through this live in an interview is a strong signal.
13. What are refs and HEAD, and what is a detached HEAD?
Answer: Refs are human-readable names that point to commit hashes: branches live under refs/heads/, tags under refs/tags/, remote-tracking branches under refs/remotes/. HEAD is normally a symbolic ref that points to the current branch (.git/HEAD contains ref: refs/heads/main); when you commit, the branch HEAD points to moves forward. A detached HEAD means HEAD points directly at a commit rather than a branch, which happens when you check out a tag, a commit hash or a remote-tracking branch directly. You can look around and even commit, but new commits belong to no branch and become hard to find once you switch away. If you want to keep work done in detached HEAD, run git switch -c rescue-branch before leaving.
14. What actually happens when you run git commit, and what are packfiles?
Answer: Git writes blobs for staged file contents (if not already present), writes tree objects for the directory structure from the index, writes a commit object pointing at the root tree and the current commit as parent, and finally moves the current branch ref to the new commit. Nothing is overwritten; history only grows. New objects start as individually compressed "loose" objects. Periodically, git gc (often run automatically) packs them into packfiles, which store similar objects as deltas against each other, and prunes unreachable objects after a grace period. This is why a repository with long history can still be compact, and why a large binary file committed once stays in every clone forever unless history is rewritten.
15. What is the reflog, and why is it your safety net?
Answer: The reflog is a local log of where HEAD and each branch have pointed over time: every commit, checkout, reset, rebase and merge adds an entry. git reflog shows entries such as HEAD@{2}: commit: add retry logic. Because Git does not delete commits immediately when nothing references them, the reflog lets you recover after a bad reset, a botched rebase or a deleted branch. By default, reachable reflog entries expire after 90 days and unreachable ones after 30 days (configurable through gc.reflogExpire and gc.reflogExpireUnreachable). Two limits: the reflog is local only, never pushed, and it does not track uncommitted work.
Interview tip: Mention ORIG_HEAD too. Operations like reset, rebase and merge save the previous tip there, so git reset --hard ORIG_HEAD undoes the last one directly.
Branching, merging, rebasing and undoing
16. How does git merge work, and what is a fast-forward merge?
Answer: git merge feature integrates another branch's commits into the current one. If the current branch has not moved since the feature branched off, Git simply moves the pointer forward: a fast-forward, no merge commit. If both branches have new commits, Git does a three-way merge using the two tips and their common ancestor (git merge-base), and records a merge commit with two parents. The default merge strategy in current Git is ort. --no-ff forces a merge commit even when a fast-forward is possible, preserving the fact that a feature existed as a unit; --ff-only refuses to merge unless a fast-forward is possible.
17. Git rebase vs merge: what is the difference, and when do you use each?
Answer: Both integrate changes; they differ in the history they produce. Merge preserves history exactly as it happened and adds a merge commit. Rebase replays your commits one by one on top of another base, producing new commits with new hashes and a linear history. Use rebase on your own, unpublished feature branch to catch up with main and tidy commits before review. Use merge to integrate shared branches, or whenever rewriting would affect other people.
| Aspect | Merge | Rebase |
|---|---|---|
| History | True history, with merge commits | Linear, rewritten |
| Commit hashes | Unchanged | New hashes for replayed commits |
| Conflicts | Resolved once, in the merge commit | Possibly once per replayed commit |
| Safe on shared branches | Yes | No, unless everyone coordinates |
| Typical use | Integrating into main or release branches | Updating a private feature branch |
Interview tip: Avoid declaring one "correct". Say your team's choice usually follows from the PR merge method (Q29) and whether you want linear history on main.
18. What is the golden rule of rebasing, and what is --force-with-lease?
Answer: Do not rebase commits that others have already based work on. Rebasing replaces commits with new ones; anyone who pulled the old ones now has divergent history and may re-introduce the old commits when they merge. Rebasing your own pushed feature branch is common, but then you must force-push. Use git push --force-with-lease rather than --force: it only overwrites the remote branch if it still points where your remote-tracking branch says it does, so you do not silently destroy a teammate's push you have not fetched yet. Protected branches (Q30) should block force pushes to main entirely.
19. How do you squash or clean up commits with interactive rebase?
Answer: git rebase -i HEAD~4 opens a todo list of the last four commits, where you can pick, reword, edit, squash (combine and merge messages), fixup (combine and discard the message), drop or reorder them. A faster workflow during review: when a reviewer asks for a change to an earlier commit, make the fix and run git commit --fixup <sha>; later, git rebase -i --autosquash main automatically moves each fixup under its target. Squashing is useful to hide "fix typo" noise before merge; many teams get the same effect by using the squash merge method on pull requests.
20. What is git cherry-pick, and when should you use it?
Answer: git cherry-pick <sha> applies the changes introduced by one commit onto the current branch as a new commit. The classic use is backporting a fix: the fix lands on main, and you cherry-pick it onto release/2.3. Use -x so the new commit message records "(cherry picked from commit ...)", which makes audits and later merges easier to understand. Cherry-pick is a precise tool, not a branching strategy: if you find yourself cherry-picking dozens of commits between long-lived branches, the branching model is the problem.
21. What is the difference between git revert and git reset (soft, mixed, hard)?
Answer: git revert <sha> creates a new commit that undoes an earlier one. History is preserved, so it is safe on shared, pushed branches. git reset moves the current branch pointer backwards, effectively removing commits from the branch; use it only on local or private history. Its three modes differ in what happens to the changes from the removed commits:
| Command | Branch pointer | Index (staging) | Working tree |
|---|---|---|---|
git reset --soft HEAD~1 | Moved back | Changes kept, staged | Unchanged |
git reset --mixed HEAD~1 (default) | Moved back | Reset, changes unstaged | Unchanged |
git reset --hard HEAD~1 | Moved back | Reset | Changes discarded |
git revert HEAD | New commit added | Matches new commit | Matches new commit |
Real-world example: "Undo my last commit but keep the work" is git reset --soft HEAD~1. "Undo a commit that is already on main" is git revert. --hard deletes uncommitted work permanently, which the reflog cannot bring back.
22. How do you revert a merge commit, and what is the catch?
Answer: A merge commit has two parents, so Git needs to know which side is the "mainline": git revert -m 1 <merge-sha> undoes the changes the merge brought in, relative to the first parent (the branch you merged into). The catch: Git still considers the feature branch's commits merged. If you later fix the feature and merge the same branch again, only the new commits come in, and the original changes stay reverted. The fix is to revert the revert commit first, then merge the new work.
23. What is git stash, and when would you use a worktree instead?
Answer: git stash saves uncommitted changes onto a stack and cleans your working tree so you can switch context. git stash push -u -m "wip: login form" includes untracked files and a label; git stash list shows entries; git stash pop applies and drops the latest; git stash apply stash@{1} applies without dropping; git stash drop removes one. Stash is for short interruptions. For longer parallel work, such as a production hotfix while a large feature is half-done, git worktree add ../hotfix -b hotfix creates a second working directory attached to the same repository, so you never have to stash at all.
Interview tip: Stashes are easy to forget. If someone dropped one by mistake, git fsck --unreachable lists unreachable commits, and stash entries are commits, so it can often be found.
24. How do you resolve merge conflicts?
Answer: A conflict happens when both sides changed the same lines (or one modified a file the other deleted) and Git cannot decide. Steps: run git status to list conflicted files (git diff --name-only --diff-filter=U gives just the names); open each file, where Git has inserted <<<<<<<, ======= and >>>>>>> markers; edit to the correct combined result; git add the file; then git commit (for a merge) or git rebase --continue. git mergetool opens a configured visual tool; git checkout --ours or --theirs <file> takes one side wholesale. Always build and run tests before concluding, because a conflict-free merge can still be semantically broken.
Production consideration: During a rebase, "ours" and "theirs" are swapped compared with a merge: "ours" is the branch you are rebasing onto and "theirs" is your commit being replayed. Enable rerere.enabled if you resolve the same conflict repeatedly; Git records and reuses your resolution. git merge --abort and git rebase --abort return you to the starting point.
25. What is git bisect, and how does it help in debugging?
Answer: git bisect does a binary search through history to find the commit that introduced a bug. Mark a known bad and a known good commit (git bisect start <bad> <good>); Git checks out a commit halfway between; you mark it git bisect good or git bisect bad; repeat until Git names the first bad commit. Better still, automate it: git bisect run ./test.sh runs a script where exit code 0 means good and non-zero means bad. Finish with git bisect reset. Bisect works well only when every commit builds, which is another argument for small, self-contained commits.
26. How do you find out who changed a line, or when a piece of code appeared or disappeared?
Answer: git blame <file> shows the last commit to touch each line; -w ignores whitespace and --ignore-rev (or a .git-blame-ignore-revs file) skips mass-formatting commits. The "pickaxe" git log -S "functionName" finds commits where the number of occurrences of a string changed, which is how you find when a function was added or removed; -G takes a regex. git log -p --follow <file> follows a file's history across renames.
GitHub interview questions: collaboration and governance
27. Compare trunk-based development, GitHub flow and GitFlow. Which branching strategy would you choose?
Answer: The right Git branching strategy follows from how you release. Trunk-based development: everyone integrates small changes into main at least daily, using very short-lived branches and feature flags to hide unfinished work; it needs strong automated tests and suits continuous delivery. GitHub flow: branch from main, open a pull request, review, merge, deploy; simple and close to trunk-based with PRs as the gate. GitFlow: long-lived develop and main branches plus feature, release and hotfix branches; suits software shipped as versioned releases with several versions supported in parallel, but adds merge overhead and slows integration.
| Strategy | Long-lived branches | Fits | Main risk |
|---|---|---|---|
| Trunk-based | main only | Web services, continuous delivery | Needs flags and solid CI discipline |
| GitHub flow | main only | Most product and platform teams | Long-running PRs drift from main |
| GitFlow | main, develop, release/* | Versioned, installed software | Merge overhead, late integration |
Real-world example: Consider a GCC team in Hyderabad running internal microservices deployed several times a day: GitHub flow with protected main and feature flags fits. The same company's on-premise banking product, with customers on three supported versions, may reasonably keep release branches and cherry-pick fixes back to them.
28. What is a pull request, how is it different from pushing code, and what makes a good code review?
Answer: Pushing moves commits to a remote branch. A pull request is a GitHub workflow object on top of that: a proposal to merge one branch into another, with a diff, discussion, review approvals, status checks from CI, and a recorded decision. PRs are how teams collaborate on GitHub, alongside issues for tracking work and discussions for questions. A good review checks correctness, tests, security (input handling, secrets, permissions), readability and whether the change matches the intent described in the ticket. Good PRs are small and focused, have a description explaining why, link the issue, and keep CI green.
Interview tip: Say how you review, not just what. For example: read the description and tests first, run the branch locally for anything non-trivial, separate blocking comments from suggestions, and approve only what you understand.
29. What merge methods does GitHub offer for pull requests?
Answer: Three. Create a merge commit keeps all PR commits and adds a merge commit, preserving full history. Squash and merge combines the PR into one commit on the base branch, giving one commit per PR and a clean, revertable main, at the cost of losing the individual commits on main. Rebase and merge replays each commit onto the base without a merge commit, giving linear history with every commit kept. Repository admins can disable methods they do not want. Squash is a common default for product teams; merge commits suit teams that value exact history; rebase merges suit teams that curate commits carefully. A merge queue can additionally serialise merges so each PR is tested against the latest main before landing.
30. What are protected branches and rulesets on GitHub?
Answer: Both enforce policy on important branches. Branch protection rules apply to a branch pattern and can require pull requests before merging, a number of approving reviews, code-owner review, passing status checks, up-to-date branches, conversation resolution, signed commits and linear history, and can block force pushes and deletion. Rulesets are the newer, more flexible model: a named set of rules that can target branches or tags by pattern, can be layered (several rulesets apply together, with the most restrictive outcome winning), can have explicit bypass lists, can be enabled or disabled without deleting them, and can be defined at organisation level to cover many repositories.
Production consideration: Keep admin bypass narrow and audited. A common gap is "require PR review" on main while release tags remain unprotected, so anyone with write access can move a production tag. Rulesets can protect tags too. Feature details evolve; check current GitHub documentation when designing org-wide policy.
31. What is a CODEOWNERS file?
Answer: CODEOWNERS maps file path patterns to the users or teams responsible for them, for example /infra/ @org/platform-team or *.tf @org/cloud-reviewers. GitHub automatically requests review from code owners when a PR touches their files, and with "require review from code owners" enabled in branch protection or a ruleset, those approvals become mandatory. GitHub looks for the file in .github/, the repository root or docs/. Patterns follow gitignore-style syntax and the last matching pattern wins, so put general rules first and specific ones later. Owners need write access to the repository for their review to count.
Real-world example: Consider an insurer's monorepo: payments code is owned by the payments team, Terraform by the platform team and the CODEOWNERS file itself by a small security group, so nobody can quietly remove themselves from review.
32. What are signed commits, and why do they matter?
Answer: Git lets anyone set any name and email in user.name and user.email, so a commit's author field proves nothing. Signing attaches a cryptographic signature that the hosting platform verifies against the public key registered on the user's account, showing a "Verified" badge. Git supports GPG, SSH and X.509 (S/MIME) signatures. SSH signing is the simplest to adopt: git config gpg.format ssh, git config user.signingkey ~/.ssh/id_ed25519.pub, then git commit -S or commit.gpgsign true. Locally, git log --show-signature and git verify-commit check signatures (SSH verification needs an allowed-signers file). Branch protection and rulesets can require signed commits.
Interview tip: Signing proves which key made the commit, not that the code is safe. Pair it with review, CI and protected branches. Commits that GitHub creates on your behalf through the web interface, such as squash merges, are signed with GitHub's own key.
33. How do GitHub repository permissions and visibility work?
Answer: On a personal repository, the owner has full control and collaborators get push access. In an organisation, repository roles are more granular: Read, Triage, Write, Maintain and Admin, assigned to teams rather than individuals wherever possible, and organisations can define custom roles on suitable plans. Visibility is public (anyone can view and fork), private (only people granted access) or, for enterprise accounts, internal (visible to members of the enterprise). The principle is least privilege: most engineers need Write, few need Admin, and automation should use narrowly scoped GitHub Apps or fine-grained tokens rather than a person's classic personal access token with broad scopes.
34. How do you secure a GitHub repository? What security features does GitHub offer?
Answer: Start with identity and access: require two-factor authentication, use SSO where available, keep Admin rare, use teams and least-privilege roles, and prefer short-lived credentials. Then protect the code path: branch protection or rulesets on main and release tags, required reviews and code owners, required CI checks, signed commits where needed. Then use the platform's security features, described generally: dependency alerts and automated update PRs (Dependabot), secret scanning with push protection that blocks recognised secrets before they land, code scanning (static analysis such as CodeQL) on PRs, dependency review that flags vulnerable packages introduced by a PR, and security advisories and private vulnerability reporting for coordinating fixes. Availability of some features depends on repository visibility and plan, so check current GitHub documentation.
Interview tip: Connect this to DevSecOps: the repository is the first control point of the software supply chain. The DevSecOps interview questions guide covers the pipeline-side gates.
35. What are GitHub Actions, and how is a workflow structured?
Answer: GitHub Actions is GitHub's built-in CI/CD and automation service. A workflow is a YAML file in .github/workflows/ that runs on events (push, pull_request, schedule, workflow_dispatch for manual runs, and many more). A workflow contains jobs, which run in parallel by default on runners (GitHub-hosted or self-hosted) unless linked with needs. Each job has steps that either run shell commands or use reusable actions. Matrices run a job across versions or platforms; environments add protection rules such as required reviewers before deploying to production; secrets and variables are injected at runtime.
name: ci
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: make test
For deployment pipelines and GitOps with Argo CD on top of Actions, the GitOps and GitHub Actions course builds these workflows hands-on, from PR checks to environment-gated releases.
Advanced Git: hooks, monorepos, LFS and history rewriting
36. What are Git hooks, and how does the pre-commit framework fit in?
Answer: Hooks are scripts Git runs at points in its workflow. Client-side hooks include pre-commit (lint, format, secret scan before the commit is created), commit-msg (enforce message conventions), and pre-push (run quick tests). Server-side hooks such as pre-receive run on the server and can reject pushes; GitHub.com does not let you run arbitrary server hooks, so enforcement there comes from rulesets, push protection and required checks. Hooks in .git/hooks are not cloned, so teams share them by committing a hooks folder and setting core.hooksPath, or use the pre-commit framework: a .pre-commit-config.yaml lists hooks (formatters, linters, secret scanners), developers run pre-commit install once, and CI runs pre-commit run --all-files.
Production consideration: Any local hook can be skipped with git commit --no-verify. Treat hooks as fast feedback for developers and repeat the same checks in CI as the real gate.
37. Monorepo vs polyrepo: what are the trade-offs, and how do you keep a large repository fast?
Answer: A monorepo keeps many projects in one repository: atomic cross-project changes, one place for tooling and shared code, easier large refactors. Costs: clone and CI time grow, ownership boundaries must be enforced with CODEOWNERS, and CI must build only what changed (path filters or a build tool that understands the dependency graph). Polyrepos give clear ownership and independent release cycles but make cross-cutting changes and dependency version alignment harder. To keep big repositories fast: partial clone (git clone --filter=blob:none) downloads file contents on demand, sparse-checkout (git sparse-checkout set --cone services/payments) limits the working tree to the directories you need, shallow clones (--depth) suit CI jobs that need no history, and background maintenance (git maintenance start) keeps the repository optimised.
38. What is a Git submodule, and how does it compare with a subtree?
Answer: A submodule embeds another repository at a path by recording a specific commit of it (a "gitlink") plus its URL in .gitmodules. The parent pins an exact version; updating means checking out a newer commit in the submodule and committing the new pointer. Clones need git clone --recurse-submodules or git submodule update --init --recursive. A subtree (git subtree add --prefix=vendor/lib <url> main --squash) copies the other project's files into a subdirectory of the parent's own history; consumers need nothing special.
| Aspect | Submodule | Subtree |
|---|---|---|
| What the parent stores | A pointer to a commit | The actual files |
| Clone experience | Extra init and update step | Plain clone works |
| Pinning a version | Explicit and exact | Implicit in history |
| Contributing back upstream | Natural (it is a real repo) | Possible with subtree push, more awkward |
| Common pain | Forgotten updates, detached HEAD inside | Larger parent history |
39. What is Git LFS, and how should teams handle large model files?
Answer: Git stores every version of every file in every clone, so large binaries bloat repositories permanently. Git LFS (Large File Storage) replaces matching files in Git with small text pointers (version, SHA-256 oid, size) and stores the real content on an LFS server. Set it up with git lfs install and git lfs track "*.safetensors", which writes a rule to .gitattributes that must be committed. git lfs migrate import --include="*.bin" --everything converts existing history, which rewrites commits. GitHub also blocks individual files larger than 100 MiB in regular Git, which is often what forces the conversation.
Real-world example: For AI teams, LFS is fine for small, slow-changing assets, but multi-gigabyte model weights and datasets usually belong in object storage or a model registry, referenced from Git by version and checksum. LFS storage and bandwidth have plan-based quotas, and pulling large weights in every CI run wastes time. Commit the code, configuration and model card; keep the weights in artifact storage.
40. How do you rewrite history to remove a file or a secret? Why git filter-repo?
Answer: git filter-repo is the tool the Git project itself recommends for history rewriting; it is faster and safer than the old git filter-branch, which Git's documentation now discourages. It is installed separately. Common uses: remove a file from all history with git filter-repo --path .env --invert-paths; replace secret strings with git filter-repo --replace-text replacements.txt, where each line looks like oldvalue==>REMOVED; extract a subdirectory into its own repository with --subdirectory-filter. It refuses to run on a repository that is not a fresh clone unless you pass --force, and it removes the origin remote afterwards to stop you accidentally pushing over the original.
Production consideration: Rewriting changes every hash from the first modified commit onward. Coordinate a freeze, force-push all affected branches and tags, and ask everyone to re-clone; any old clone or fork still contains the original objects.
41. How do you secure GitHub Actions workflows?
Answer: Treat workflows as production code with production credentials. Set a minimal permissions: block so the automatic GITHUB_TOKEN can only do what the job needs (often contents: read). Use OpenID Connect (OIDC) federation to get short-lived cloud credentials from AWS, Azure or Google Cloud instead of storing long-lived keys as secrets. Pin third-party actions to a full commit SHA rather than a mutable tag, and let Dependabot update them. Be careful with pull_request_target and other triggers that run with repository secrets on code from forks; never check out and execute untrusted PR code in that context. Do not interpolate untrusted input such as PR titles directly into shell run: lines. Protect deploy jobs with environments that require reviewers, and restrict self-hosted runners to trusted repositories because a runner executes whatever the workflow tells it to.
The same pipeline patterns for AI services, including evaluation gates, are covered in CI/CD for AI applications.
AI in Git workflows
42. How are AI code review and AI-generated PR summaries used, and what are their limits?
Answer: AI assistants, including GitHub Copilot's PR features and third-party review bots, can draft a pull request description from the diff, summarise a large PR for reviewers, and leave review comments pointing out likely bugs, missing null checks, inconsistent naming or absent tests. Used well, they speed up the first pass and help reviewers focus. Their limits are real: they see the diff and some surrounding context, not the business intent, the production traffic pattern or the incident that motivated a design; they can be confidently wrong; and they can produce plausible but generic comments that add noise. A summary can omit the one risky change in a large PR.
Interview tip: Position AI review as an additional reviewer, never a replacement for a required human approval from someone accountable for the code. Keep human code-owner review and CI as the merge gate. Feature names and availability change, so describe capabilities rather than promising specific products.
43. How would you govern AI-generated code in a team's Git workflow?
Answer: The same rules as any code, applied more consistently. AI-generated code goes through the same PR, review, tests and security scanning; the author remains accountable and must be able to explain it. Practical controls: require tests for generated logic, keep PRs small even when an assistant can generate a lot, run secret scanning and static analysis (assistants can reproduce credential-like strings or insecure patterns), check dependency suggestions against approved package lists because assistants sometimes suggest packages that do not exist, and follow your organisation's policy on licensing, data sent to the assistant, and disclosure in PR descriptions. The enterprise adoption angle, including policies and measurement, is covered in AI coding assistants in the enterprise.
44. An AI agent will open pull requests in your repositories. How do you set it up safely?
Answer: Give the agent its own identity, ideally a GitHub App with fine-grained, repository-scoped permissions (for example contents write on feature branches and pull requests write, nothing else), never a human's token. Let it push only to its own branch prefix; protected branches and rulesets stop it from merging to main or editing workflows. Require human code-owner approval and passing CI on every agent PR. Log its actions, label its PRs clearly, rate-limit it, and keep a kill switch. Because PR text, issue bodies and code comments are untrusted input to the agent, guard against prompt injection that tries to make it exfiltrate secrets or change permissions.
Real-world example: The GitHub AI agent project walks through building an agent that triages issues and drafts PRs with exactly these guardrails.
Real-world scenario questions
45. A teammate deleted a feature branch that was never merged or pushed. How do you recover it?
Answer: Commits are not deleted when a branch is; only the pointer is. Find the last commit of the branch in the reflog and recreate the branch there.
What I would check:
- Run
git reflog(on the machine where the work was done, since the reflog is local) and look for entries likecommit: ...orcheckout: moving from feature-x to main.git branch -Dalso prints "Deleted branch feature-x (was a89e1ba)", which may still be in the terminal scrollback. - Recreate it:
git branch feature-x a89e1ba(orgit branch feature-x HEAD@{1}if that reflog entry is the tip). - Verify with
git log --oneline feature-xand push it to the remote straight away. - If the reflog has nothing, try
git fsck --lost-foundorgit fsck --unreachableto list dangling commits, then inspect them withgit show. - If the branch had been pushed, check whether the remote, a CI checkout or another teammate's clone still has it; on GitHub, a recently deleted branch with a PR can usually be restored from the PR page.
Production consideration: Recovery depends on garbage collection not having pruned the objects yet. Act quickly, and do not run git gc --prune=now while investigating.
46. You pushed a bad commit to main and others have already pulled. How do you undo it?
Answer: Use git revert <sha> and push the revert commit, through a PR if main is protected. Do not reset and force-push a shared branch: everyone who pulled now has history that conflicts with the rewritten remote.
What I would check:
- Identify exactly which commit or commits are bad (
git log --oneline, the PR, the deploy record). - For several consecutive commits,
git revert --no-edit OLDEST^..NEWESTcreates one revert per commit; add--no-committo combine them into a single revert. - If the bad change came in through a merge commit, use
git revert -m 1 <merge-sha>and remember the re-merge catch from Q22. - Run CI on the revert and deploy it; confirm the symptom is gone.
- Only if the commit is very recent, nobody has pulled, and branch policy allows it, consider
git resetplusgit push --force-with-lease; in practice protected branches should prevent that onmain.
Production consideration: If the bad commit contained a secret, a revert is not enough: the secret is still in history. That is Q47.
47. A developer committed an AWS access key and pushed it to GitHub. What do you do?
Answer: Revoke and rotate the credential first, immediately. Assume it is compromised the moment it reached a remote; automated scanners look for exactly this. Cleaning history comes second and is about hygiene, not safety.
What I would check:
- Deactivate the key and issue a new one through the owning team; update the systems that legitimately used it from a secrets manager, not from Git.
- Review cloud audit logs (for example CloudTrail on AWS) for activity using the key since it was pushed, and follow the incident process if anything unexpected appears.
- Remove it from history on a fresh clone:
git filter-repo --path config/.env --invert-pathsfor a whole file, orgit filter-repo --replace-text replacements.txtto redact the string. Force-push affected branches and tags, and ask everyone to re-clone. - Remember copies outside your control: forks, open PR refs, CI caches and other clones. On GitHub, cached views may need a request to GitHub Support; check current documentation.
- Prevent a repeat: enable secret scanning with push protection, add a secret scanner to pre-commit and CI, add the file to
.gitignore, and move to short-lived credentials such as OIDC for CI.
Production consideration: In an interview, the order matters more than the command. Candidates who start with filter-repo and mention rotation as an afterthought lose points.
48. You are halfway through a rebase with conflicts everywhere and it is going badly. What now?
Answer: Stop and get back to a known state: git rebase --abort returns the branch to exactly where it was before the rebase started. If you already finished a bad rebase, the old tip is in ORIG_HEAD and the reflog, so git reset --hard ORIG_HEAD (or git reset --hard feature@{1}) undoes it.
What I would check:
- Why so many conflicts? A long-lived branch replayed commit by commit can hit the same conflict repeatedly. Squashing your own commits first (
git rebase -i, then rebase once) or doing a singlegit merge mainmay be far simpler. - Was a mass reformat or file move on
maininvolved? Resolve it once deliberately rather than in every commit. - Enable
rerere.enabled trueso repeated resolutions are reused. - If the branch was based on another feature branch that has since been squash-merged, use
git rebase --onto main old-base featureto replay only your own commits. - Before force-pushing the result, compare old and new with
git range-diffand run tests, then push with--force-with-lease.
49. Your merge conflicts in package-lock.json (or another lockfile). How do you resolve it?
Answer: Do not hand-edit conflict markers in a generated lockfile. Resolve the manifest (package.json) correctly, take one side of the lockfile as a starting point, then let the package manager regenerate it.
What I would check:
- Resolve any conflict in
package.jsonfirst, deciding which dependency versions both branches need. - Take the target branch's lockfile as the base: during a merge into your branch,
git checkout --theirs package-lock.jsontakes the incoming side; during a rebase, remember that ours and theirs swap (Q24). - Run the package manager install (for example
npm install) so it recomputes the lockfile from the merged manifest, thengit add package-lock.jsonand continue the merge or rebase. - Run the build and tests; review the lockfile diff for unexpected major version jumps.
- The same pattern applies to
yarn.lock,pnpm-lock.yaml,poetry.lock,go.sumand Terraform's.terraform.lock.hcl.
Production consideration: Frequent lockfile conflicts usually mean long-lived branches or many uncoordinated dependency bumps. Grouped automated dependency PRs and shorter branches reduce them.
50. You committed three commits to main locally instead of a feature branch, and have not pushed. Fix it.
Answer: Create a branch at the current commit, then move main back. The commits stay on the new branch.
git branch feature-x(the new branch points at your latest commit).git reset --hard origin/mainmoves localmainback to the remote's state. Make sure the working tree is clean first, since--harddiscards uncommitted changes.git switch feature-x, push it and open a PR.
Production consideration: If you had already pushed to a protected main, the push would have been rejected, which is the point of protection. If it was not protected and others pulled, use revert instead (Q46).
51. Someone ran git reset --hard and thinks they lost a day of work. What can be recovered?
Answer: It depends on whether the work was committed. Committed work is recoverable from the reflog: git reflog, find the commit before the reset, then git reset --hard HEAD@{n} or create a branch at it. Staged but uncommitted files left blob objects behind, so git fsck --lost-found can dump them into .git/lost-found/, without filenames. Changes that were never staged are gone from Git's point of view; check the editor's local history, IDE caches or backups.
What I would check:
git reflogfor the pre-reset commit.git stash list: the work may have been stashed, and a dropped stash can be found withgit fsck --unreachable.git fsck --lost-foundfor staged content.- Editor or IDE local history.
Production consideration: Teach the habit: commit early on a branch, even messy work-in-progress, and clean up with interactive rebase later. Commits are cheap and recoverable; uncommitted work is neither.
52. A teammate force-pushed and overwrote commits on a shared branch. How do you restore them?
Answer: Anyone who fetched before the force-push still has the old commits. Find the old tip and push it back, after agreeing with the team.
What I would check:
- On a clone that fetched earlier,
git reflog show origin/shared-branchshows previous positions of the remote-tracking branch; the force-push itself also prints "+ old...new (forced update)". - Create a branch at the old tip and compare:
git log new-tip..old-tipshows what was lost. - Decide whether to restore the old tip or merge the lost commits into the new one, then push (a restore needs a force-push, so coordinate).
- On GitHub, the PR timeline and activity logs record force-pushes and the previous head commit, which helps locate it.
- Prevent it: block force pushes on shared branches with protection or rulesets, and teach
--force-with-lease.
53. A push is rejected because a 300 MB model file is in history. How do you fix it?
Answer: Removing the file in a new commit is not enough, because the push still includes the earlier commit that added it. You must rewrite the unpushed history so the file never appears, then store it properly.
What I would check:
- Find which commits added it:
git log --oneline --stat -- path/to/model.bin. - If it is only in local, unpushed commits, either convert it to LFS with
git lfs migrate import --include="*.bin", or remove it withgit filter-repo --path path/to/model.bin --invert-pathson a fresh clone. For one recent commit,git reset --soft HEAD~1, unstage the file and recommit is enough. - Add the pattern to
.gitignoreor an LFS rule so it does not happen again. - Decide where the model belongs: for large weights, object storage or a model registry with the version recorded in Git (Q39).
- Add a pre-commit hook that rejects files above a size limit.
54. Main has moved far ahead, but you must ship a critical fix to the release branch that customers run. How?
Answer: Fix forward on main first so the fix is never lost, then backport it to the release branch with cherry-pick, and release from a tag.
What I would check:
- Land the fix on
mainthrough a normal PR, as one focused commit. git switch -c hotfix/2.3.1 origin/release/2.3, thengit cherry-pick -x <fix-sha>. Resolve any conflicts caused by code that differs between versions.- Open a PR into
release/2.3so CI runs against that branch, get it reviewed, merge, and create an annotated tagv2.3.1. - If the fix was urgent enough to start on the release branch, cherry-pick it forward to
mainimmediately afterwards, and track it so it is not forgotten.
Production consideration: Consider a bank running an on-premise version of an internal platform: auditors will ask which commits went into v2.3.1 and who approved them. The -x trailer, the PR and the signed tag answer that question.
55. CI checkout of your monorepo takes minutes and some jobs fail on missing history. What do you change?
Answer: Fetch only what each job needs, and fetch history only where it is really used.
What I would check:
- Most CI checkout actions, including GitHub's own
actions/checkout, default to a shallow clone of one commit. That is fast but breaks jobs that need history, such as changelog generation,git describefor versions, or diffing against the base branch. Fetch more only in those jobs (fetch-depth: 0for full history, or a targetedgit fetchof the base branch). - Use partial clone (
--filter=blob:none) and sparse-checkout so a payments job checks out only the payments service and shared libraries. - Add path filters so workflows run only when relevant directories change.
- Move large binaries out of the repository or behind LFS, and fetch LFS objects only in jobs that need them.
Key takeaways
- Know the model: blobs, trees, commits and refs. Most "magic" in Git becomes obvious once you see a branch is a pointer and a commit hash covers all its history.
- Rebase private branches, merge shared ones, and use
--force-with-leasewhenever you must force-push. - Revert on shared branches; reset only on local history. Know what soft, mixed and hard do to the index and working tree.
- The reflog and
ORIG_HEADare your safety net for committed work. Uncommitted work has no net, so commit early. - For a leaked secret, rotate first, then clean history with
git filter-repo, then prevent with push protection and scanning. - On GitHub, combine protected branches or rulesets, CODEOWNERS, required checks and least-privilege access; treat Actions workflows as privileged code.
- AI review and PR summaries help reviewers, but human code-owner approval and CI stay the merge gate.
Interview preparation checklist
- Create a scratch repository and inspect objects with
git cat-file -pon a commit, a tree and a blob. - Run each reset mode on a throwaway commit and check
git statusafter each. - Delete an unmerged branch, then recover it from
git reflog. - Create a merge conflict on purpose, resolve it by hand, then repeat during a rebase and notice ours and theirs swap.
- Revert a merge commit with
-m 1and try re-merging the branch to see the catch. - Use
git bisect runwith a small test script. - Commit a fake secret in a test repo and remove it with
git filter-repo; note that the origin remote is removed. - Set up SSH commit signing and verify a commit with
git verify-commit. - Write a GitHub Actions workflow with a minimal
permissions:block that runs tests on pull requests. - Write a CODEOWNERS file and a pre-commit configuration for a sample repository.
- Prepare one story about a Git mistake you made or fixed, told as problem, action and prevention.
FAQ
What Git topics are most commonly asked in DevOps interviews?
Merge versus rebase, reset versus revert, resolving conflicts, branching strategies, pull requests and protected branches come up most often, followed by recovery scenarios such as a deleted branch or a pushed secret, and GitHub Actions basics.
How should a fresher prepare for Git interview questions?
Learn the three areas (working tree, staging area, repository), the basic commands, branching and merging, and practise them daily in a real project. Then break a scratch repository on purpose and recover it, so you can explain reset, revert and reflog from experience.
Do I need to know GitHub as well as Git?
Yes, for most roles. Git covers history and branching; GitHub interview questions cover pull requests, code review, permissions, branch protection or rulesets, CODEOWNERS, security features and GitHub Actions, which teams use every day.
Is git rebase vs merge a trick question?
Not a trick, but interviewers want trade-offs rather than a favourite. Explain that rebase rewrites commits for a linear history and suits private branches, while merge preserves true history and is safe on shared branches.
Which Git commands should I be able to type from memory?
clone, status, add, commit, log, diff, switch, branch, fetch, pull, push, merge, rebase, stash, reset, revert, cherry-pick, reflog and tag. Knowing their most useful flags matters more than knowing rare commands.
How important is GitHub Actions for a Git interview?
For DevOps and platform roles it is important. Expect to explain workflows, events, jobs, runners and secrets, and to discuss securing pipelines with least-privilege tokens and short-lived cloud credentials.
Are Git skills enough to get a DevOps job?
Git is a foundation, not the whole job. DevOps roles also expect Linux, scripting, CI/CD, containers, Kubernetes, infrastructure as code and a cloud platform, with Git tying all of them together.
Will AI tools replace Git skills?
No. AI assistants can draft commits, PR summaries and review comments, but engineers still need to understand history, branching, recovery and review policy to judge what the tools produce and to fix things when they go wrong.
Git skills show their value in pipelines, and pipelines are where interviews increasingly go next. Cloudsoft's GitOps and GitHub Actions training in Hyderabad covers branching, pull request workflows, Actions pipelines and Argo CD deployments through hands-on labs, in our Ameerpet classroom or live online. If you want a broader path that takes these engineering skills into AI, ML, cloud and security work, look at the APEX AI, ML, Cloud and Cyber Security program. Call +91 96660 19191 to book a free demo.



