How do you handle version control and collaboration using Git
Branch per feature, small focused commits with clear messages, PRs with review and CI, a branching strategy (trunk-based or git-flow), rebase/merge hygiene, and conflict resolution. The collaboration part: communication, small PRs, and not breaking main.
This question checks you have disciplined Git habits and work well in a team — not Git trivia.
Workflow
1. Branching — never commit straight to main. A branch per feature/fix (feature/..., fix/...), branched from an up-to-date main.
2. Branching strategy — pick one and be consistent:
- Trunk-based — short-lived branches, merge to
mainfrequently, feature flags for incomplete work. Best for CI/CD. - Git-flow —
develop/release/hotfixbranches. Heavier; suits scheduled releases.
3. Commits — small, atomic, each one a coherent change. Clear messages (imperative mood, "Add X" not "added stuff"); many teams use Conventional Commits (feat:, fix:).
4. Pull Requests — keep them small and focused (easy to review, fewer conflicts). A description of what/why, linked issue, screenshots for UI. CI runs tests/lint/build on the PR. At least one reviewer approves before merge.
5. Keeping in sync — regularly pull/rebase main into your branch so you're not integrating a week of drift at once. git rebase for a clean linear history on your own branch; merge for shared branches (don't rebase shared history).
6. Conflict resolution — resolve locally, understand both sides before picking, re-test after resolving. Frequent small merges keep conflicts small.
7. Protecting main — branch protection: required reviews, required CI, no force-push.
The collaboration part (what they really want)
- Communicate — say what you're working on; avoid two people rewriting the same file.
- Small PRs — respect reviewers' time; big PRs get rubber-stamped.
- Review constructively — and respond to reviews promptly.
- Don't break
main— it should always be deployable. - Useful history — commits and messages that help the next person (and
git bisect).
The framing
"Branch per feature off an up-to-date main, small atomic commits with clear messages, and small focused PRs with review and CI before merge. I keep my branch synced by rebasing main in frequently so integration is continuous, not a big-bang merge. The team side matters most: communicate what you're touching, keep PRs reviewable, never break main, and leave a history the next person can actually use."
Follow-up questions
- •When do you rebase vs merge?
- •Why are small PRs better than large ones?
- •How do you resolve a merge conflict safely?
- •What is trunk-based development and when does it fit?
Common mistakes
- •Committing directly to main.
- •Huge, unfocused PRs that are impossible to review well.
- •Vague commit messages ('fix', 'updates', 'wip').
- •Rebasing shared/public branches and rewriting others' history.
- •Letting a branch drift for weeks, then fighting massive conflicts.
Performance considerations
- •Not applicable directly — but team velocity is the 'performance' here: small PRs, fast CI, and continuous integration reduce review latency and merge pain.
Edge cases
- •Resolving conflicts in generated files or lockfiles.
- •A force-push needed after rebase — only on your own branch, with --force-with-lease.
- •Reverting a bad merge that's already on main.
- •Long-lived feature branches — mitigate with feature flags.
Real-world examples
- •GitHub flow: branch → PR → review + CI → squash merge to main.
- •Feature flags letting trunk-based teams merge incomplete work safely.