Tổng hợp 53 câu hỏi phỏng vấn Git kèm đáp án chi tiết, song ngữ Việt–Anh — sắp xếp từ cơ bản đến nâng cao. Ôn luyện miễn phí, tự động lưu tiến độ.
Git Flow có 5 loại branch: main (production), develop (tích hợp code), feature/ (tính năng mới), release/ (chuẩn bị release), hotfix/ (sửa lỗi khẩn cấp). Trunk-based Development là hướng ngược lại: commit thẳng vào main với feature flags, phù hợp team CI/CD mature. Thực tế…
Merge: tạo merge commit, giữ history đầy đủ, safe cho shared branches. Rebase: rewrite history thành linear, clean hơn, KHÔNG dùng cho shared branches. Best practice: rebase feature branch lên develop trước khi merge (hoặc squash merge). git rebase -i để clean commits.
Git Flow: nhiều nhánh dài hạn — main, develop, feature/, release/, hotfix/. Hợp khi: release theo chu kỳ dài, cần maintain nhiều version song song, team lớn cần tách biệt. Nhược điểm: feature branch sống lâu → merge conflict lớn; hotfix phải merge vào cả…
GitHub Flow (đơn giản): main là production-ready, mọi tính năng làm trên branch từ main, PR → review → merge → deploy ngay. Chỉ có 1 loại branch ngoài main. Git Flow (phức tạp): main + develop + feature/ + release/ + hotfix/. Overhead cao…
Monorepo không thay đổi branching strategy cơ bản nhưng tăng complexity của conflict và CI. Recommended: trunk-based + CODEOWNERS + scoped CI CODEOWNERS (/.github/CODEOWNERS): định nghĩa team nào review phần nào: PR chỉ require approval từ owner của file được thay đổi → teams không…
Git Flow hotfix: GitHub Flow hotfix (đơn giản hơn): Lưu ý: luôn merge hotfix vào cả production branch VÀ development branch — đừng để fix bị mất ở lần deploy tới. Tag version sau hotfix để dễ rollback. Viết post-mortem sau khi hệ thống ổn…
Release branch (release/1.5.0) tách quá trình stabilize một version khỏi ongoing development. Flow: feature freeze → tạo release branch → chỉ bug fixes được merge vào → QA → deploy → merge về main + tag. Cần release branch khi: - QA cycle dài (days/weeks)…
Vào GitHub repo → Settings → Branches → Add branch protection rule cho main: Tối thiểu cần bật: - Require a pull request before merging — không ai push thẳng - Require approvals (1-2 reviewers) - Dismiss stale pull request approvals when new commits are…
Conventional Commits là convention format: type(scope): description. Types: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert. Tại sao không chỉ "agree": agreement không có enforcement = mọi người quên hoặc bỏ qua khi deadline gần. Sau 3 tháng, git log trở thành…
Interactive rebase (git rebase -i) cho phép edit lịch sử commit local trước khi share. Workflow chuẩn trước merge PR: Trong editor hiện ra: Thay đổi: - squash (s): merge commit này vào trước, giữ message - fixup (f): merge vào trước, BỎ message (dùng…
3 merge strategies trên GitHub: Merge commit (--no-ff): tạo merge commit, giữ toàn bộ history của branch. git log --graph thấy branch structure. Tốt cho: feature branches quan trọng muốn preserve full context. Squash merge: tất cả commits của PR → 1 commit trên main.…
Amend last commit — chỉ dùng khi commit CHƯA push: Nếu đã push (chỉ branch của riêng bạn): Lưu ý: - --amend tạo commit MỚI với hash khác — không phải edit in-place - KHÔNG amend commits trên main/develop hoặc bất kỳ shared branch -…
Signed commits đảm bảo commit thực sự từ người có private key tương ứng — chống giả mạo identity (bất kỳ ai cũng có thể set git config user.email thành email của bạn). Setup GPG signing: SSH signing (mới hơn, dễ hơn GPG): GitHub hiển…
Atomic commit: mỗi commit chứa MỘT logical change hoàn chỉnh — pass tests độc lập, có thể revert độc lập, message mô tả đủ ý. Tại sao commit "fat" là anti-pattern: 1. Revert bị ràng buộc: cần revert chỉ navbar fix nhưng buộc phải revert…
Merge: tạo merge commit, preserve history đầy đủ. git log --graph thấy nhánh. Non-destructive — không thay đổi existing commits. Rebase: replay commits lên trên branch khác, tạo linear history. Rewrite commit hashes. Golden Rule of Rebasing: KHÔNG BAO GIỜ rebase branch đã được share/push…
Fast-forward merge (mặc định khi có thể): nếu branch hiện tại là ancestor trực tiếp của branch cần merge, git chỉ di chuyển HEAD pointer lên — không tạo merge commit. History linear. No-ff merge (--no-ff): luôn tạo merge commit dù có thể fast-forward. Trade-offs:…
Worst case conflict: không phải thêm/xoá dòng đơn giản mà là structural refactor — function bị rename, logic được reorganize. Quy trình an toàn: 1. Hiểu context trước khi resolve: 2. Dùng 3-panel merge tool — git mergetool (trái: ours, phải: theirs, giữa: base —…
Reset (git reset --hard HEAD~1): di chuyển HEAD pointer về commit cũ, xoá commits khỏi history. KHÔNG dùng trên main/shared branch — sẽ cần force push, làm hỏng history của mọi người đã pull. Revert (git revert <commit): tạo commit MỚI undo changes của commit…
Pickaxe search — tìm commits đã thêm/xoá một chuỗi cụ thể trong code. - git log -S "string" (pickaxe): tìm commits mà số lần xuất hiện của string thay đổi (thêm hoặc xoá) — chính xác hơn khi code bị rename/move. - git log -G…
Branch chỉ là pointer đến commit. Xoá branch không xoá commits — chỉ xoá pointer. Commits vẫn tồn tại trong git object store cho đến khi git gc chạy. Recovery qua reflog: - Không nhớ tên branch: git reflog grep "checkout: moving from" — tìm…
git blame <file hiển thị mỗi dòng: commit hash, author, date, line content — ai viết dòng đó khi nào. Use cases thực sự hữu ích: 1. Hiểu context của code lạ: git blame src/utils/pricing.ts -L 23,35 → thấy dòng 28 do ai viết 6…
git push --force: overwrite remote không kiểm tra gì — nếu teammate đã push commits mới lên remote mà bạn chưa fetch, bạn sẽ overwrite và mất work của họ. git push --force-with-lease: kiểm tra remote ref trước khi overwrite — chỉ force push nếu…
Force push ACCEPTABLE: 1. Feature branch của riêng bạn, chưa ai review/pull: sau git rebase -i để clean up commits trước PR 2. Personal fork: không ảnh hưởng ai 3. Sau git commit --amend trên branch riêng: cần update remote 4. Reset --hard và force…
Credentials đã push = credentials bị compromise. Rotate ngay lập tức — đây là ưu tiên số 1. Bước 1: Rotate credentials (NGAY LẬP TỨC): - API keys, DB passwords, JWT secrets → revoke và generate mới - Không chờ xoá khỏi git — ai…
Cơ bản hay bị hiểu nhầm: - git stash = git stash push — stash working dir + index - pop = apply + drop (xoá stash sau khi apply) - apply = apply nhưng GIỮ stash (dùng khi muốn apply vào nhiều branches) Patterns…
git cherry-pick <commit copy 1 commit từ branch khác vào branch hiện tại — tạo commit mới với cùng changes nhưng hash khác. Khi cherry-pick là đúng: 1. Hotfix cần apply vào nhiều release branches: 2. Lấy 1 commit cụ thể từ branch của đồng…
Vấn đề: bạn có local commits chưa push. Teammate đã push lên remote. git pull = git fetch + git merge → tạo merge commit "Merge branch 'main' of github.com/..." không mang thông tin gì, git log --graph đầy những vòng merge vô nghĩa. Fix:…
Vấn đề nếu lint cả project trên mỗi commit: - Project lớn → eslint . mất 30-60 giây → developers tắt hooks - Không liên quan: bạn sửa 1 file nhưng phải đợi 500 files khác lint Giải pháp là lint-staged: chỉ chạy linter trên…
commit-msg hook chạy sau khi developer viết commit message — có thể reject nếu message không hợp lệ. Setup: npm i -D @commitlint/cli @commitlint/config-conventional, file .husky/commit-msg (Husky v9) chỉ chứa 1 dòng npx --no -- commitlint --edit $1. commitlint.config.js: Cho phép WIP commits (không block…
pre-push hook chạy trước khi git push — có thể block push nếu tests fail. Trade-off chính: - Bảo vệ remote branch khỏi broken code - Nhưng full test suite có thể mất 5-10 phút → developers tìm cách lách (push thẳng không qua hook)…
git fetch tải commits/refs mới từ remote về remote-tracking branches (origin/main) — KHÔNG đụng vào working directory hay local branch. git pull = git fetch + git merge (hoặc + git rebase nếu config pull.rebase) — tích hợp thẳng vào branch hiện tại. Chỉ nên…
Conflict xảy ra khi git không thể tự hợp nhất: 2 branch cùng sửa 1 vùng dòng của cùng file, hoặc 1 bên xoá file mà bên kia sửa. Git dừng merge và chèn conflict markers vào file: Quy trình resolve: 1. git status —…
Bình thường HEAD trỏ vào một branch; commit mới sẽ kéo branch đi theo. Khi bạn git checkout <commit-hash (hoặc checkout tag), HEAD trỏ thẳng vào commit — trạng thái "detached HEAD". Code vẫn xem/build/test được bình thường, nhưng commit mới tạo ở đây không…
.gitignore chỉ có tác dụng với file chưa được track. File đã commit thì git tiếp tục track bất kể .gitignore — phải gỡ khỏi index: Lưu ý: - Thiếu --cached → git rm xoá luôn file thật trên disk - File vẫn nằm trong…