Giải quyết merge conflict như thế nào?
Conflict xảy ra khi hai nhánh sửa cùng vùng dòng. Mở file có marker conflict, chọn nội dung đúng, xoá marker, git add file rồi git commit (hoặc git rebase --continue). Có thể huỷ bằng git merge --abort.
git fetch và git pull khác nhau thế nào?
git fetch chỉ tải commit mới từ remote và cập nhật nhánh remote-tracking (origin/main), không đụng vào nhánh hiện tại. git pull = fetch + merge (hoặc rebase với --rebase) vào nhánh hiện tại, nên có thể gây conflict ngay.
git merge và git rebase khác nhau thế nào?
merge tạo merge commit, giữ nguyên lịch sử; rebase viết lại commit của nhánh lên đỉnh nhánh đích để lịch sử thẳng. Không rebase nhánh đã push và có người khác dùng.
git reset, revert và checkout/restore khác nhau thế nào?
reset di chuyển nhánh về commit cũ (viết lại lịch sử); revert tạo commit mới đảo ngược thay đổi (an toàn với nhánh chung); restore khôi phục file trong working tree.
Working directory, staging area và repository trong Git
File đi qua ba vùng: working directory (đang sửa), staging area/index (git add, chọn thay đổi sẽ vào commit tiếp theo) và repository (git commit lưu snapshot). Staging cho phép commit chỉ một phần thay đổi.
git reflog cứu commit bị mất như thế nào?
reflog ghi lại mọi lần HEAD và các ref di chuyển trong repo local (checkout, commit, reset, rebase). Sau reset --hard hoặc rebase hỏng, tìm hash cũ trong git reflog rồi git reset --hard hoặc git branch để khôi phục; commit chưa bị gc thì vẫn lấy lại được.
GitFlow và trunk-based development: chọn cái nào?
GitFlow dùng nhiều nhánh dài hạn (main, develop, release, hotfix), hợp với phát hành theo phiên bản có chu kỳ. Trunk-based có một nhánh chính, nhánh feature rất ngắn, tích hợp liên tục và dùng feature flag, hợp với CI/CD và deploy thường xuyên.
Interactive rebase để squash và dọn lịch sử commit
git rebase -i <base> mở danh sách commit để pick, reword, squash, fixup, drop hoặc đổi thứ tự, viết lại lịch sử thành các commit gọn. Chỉ nên dùng trên nhánh chưa chia sẻ vì commit sinh ra có hash mới.
Khi nào dùng git stash và cherry-pick?
stash cất tạm thay đổi chưa commit để đổi nhánh; cherry-pick lấy đúng một commit từ nhánh khác áp vào nhánh hiện tại (ví dụ hotfix).
Dùng git bisect, blame, log -S để tìm nguồn gốc bug
git bisect dùng tìm kiếm nhị phân giữa commit tốt và xấu để tìm commit gây lỗi trong O(log n) bước, có thể tự động bằng script. git blame cho biết ai sửa dòng nào lần cuối; git log -S hoặc -G tìm commit thêm hoặc xoá một chuỗi.
git commit --amend và vì sao nên dùng --force-with-lease
commit --amend thay commit cuối bằng commit mới (đổi message hoặc thêm file) nên hash đổi. Nếu đã push, phải force push. --force-with-lease chỉ ghi đè khi remote vẫn đúng như bạn lần cuối thấy, tránh vô tình xoá commit của đồng nghiệp như --force.