Tám bài trước xoay quanh 1 repo cục bộ duy nhất. Bài này mở rộng ra tình huống thực tế nhất: nhiều người cùng làm việc trên 1 remote (thường là GitHub/GitLab). fetch, pull, push chỉ là các cách khác nhau để đồng bộ 2 đồ thị commit — repo cục bộ của bạn và repo trên server — vốn có thể phân kỳ (diverge) bất cứ lúc nào đồng nghiệp push trước bạn.

1. git fetch vs git pull: Tải Về Nhưng Không (Hoặc Có) Trộn

git fetch tải các commit mới từ remote về máy bạn và cập nhật con trỏ origin/main — nhưng không đụng tới branch main cục bộ hay Working Directory của bạn. Đây là lệnh 100% an toàn, có thể chạy bất cứ lúc nào chỉ để "xem đồng nghiệp đã làm gì" mà không ảnh hưởng việc bạn đang làm dở.

git pull đơn giản là git fetch rồi tự động trộn origin/main vào branch hiện tại của bạn — mặc định bằng merge (tạo commit hợp nhất nếu đã phân kỳ, xem lại Bài 4), hoặc bằng rebase nếu bạn chạy git pull --rebase.

2. Remote-tracking Branch: origin/main Là Gì?

origin/main không phải là branch trên remote — nó là một bản sao cục bộ, chỉ đọc, ghi nhớ "lần cuối tôi fetch, remote đang ở commit nào". Local main và local origin/main hoàn toàn có thể trỏ tới 2 commit khác nhau cùng lúc — đó chính xác là lúc bạn "phía trước" hoặc "phía sau" remote, giống hệt cơ chế con trỏ đã học ở Bài 3.

ℹ️ git fetch tuyệt đối không làm hỏng thứ gì
Vì fetch chỉ tải object mới và di chuyển con trỏ origin/main (không đụng main hay Working Directory), nó không thể gây conflict hay mất dữ liệu. Thói quen tốt: git fetch thường xuyên để luôn biết trạng thái remote, rồi tự quyết định khi nào merge hoặc rebase — thay vì để pull tự động quyết định hộ bạn.

3. git push: Fast-forward Hay Bị Từ Chối?

git push chỉ thành công khi lịch sử remote là tổ tiên trực tiếp của lịch sử bạn đang push — tức remote có thể "tiến nhanh" (fast-forward, xem lại Bài 3) tới đúng commit bạn gửi lên. Nếu ai đó đã push trước bạn kể từ lần fetch gần nhất, remote chứa commit bạn chưa có — Git từ chối với lỗi non-fast-forward, buộc bạn fetch/pull để tích hợp trước.

🕳️ Cạm bẫy thường gặp: git push --force ghi đè lịch sử người khác
--force bỏ qua kiểm tra fast-forward, ép remote nhận đúng lịch sử của bạn — kể cả khi nó xoá mất commit của đồng nghiệp. Đây là vi phạm trực tiếp Golden Rule đã học ở Bài 5: không viết lại lịch sử đã chia sẻ. Nếu thực sự cần (ví dụ sau khi rebase 1 nhánh cá nhân), luôn dùng --force-with-lease — nó từ chối ghi đè nếu ai đó đã push thêm gì mà bạn chưa fetch, an toàn hơn --force thường rất nhiều.

4. Rebase vs Merge Khi Làm Việc Nhóm

git pull (merge, mặc định) git pull --rebase
Lịch sử kết quả Có commit hợp nhất (2 cha) khi phân kỳ Tuyến tính — commit cục bộ được phát lại (replay) trên đỉnh remote
Hash commit cục bộ Giữ nguyên Đổi mới (giống cherry-pick ở Bài 6)
An toàn khi nào Luôn an toàn, kể cả commit đã push Chỉ an toàn với commit CHƯA push — đúng Golden Rule ở Bài 5

Nhiều team đặt git config pull.rebase true làm mặc định để giữ lịch sử tuyến tính, dễ đọc hơn khi nhiều người cùng push liên tục vào 1 branch.

🔬 Đào sâu: Pull Request không phải khái niệm của Git
Pull Request (GitHub) / Merge Request (GitLab) hoàn toàn là quy ước của nền tảng lưu trữ, không tồn tại trong chính Git. Về bản chất, PR chỉ là "đề xuất merge nhánh A vào nhánh B, kèm review/comment/CI check" — khi bấm nút "Merge", nền tảng chỉ đơn giản chạy đúng git merge (hoặc rebase/squash tuỳ cấu hình) mà bạn đã học ở Bài 4Bài 5 — không có phép màu Git nào khác đứng sau nó.
💡 Mẹo: xem trạng thái ahead/behind bằng git branch -vv
Lệnh này liệt kê mỗi local branch cùng branch remote-tracking nó bám theo (upstream), và số commit "ahead"/"behind" — biết ngay cần push, pull, hay cả 2 mà không cần đoán. Lần đầu push 1 branch mới, dùng git push -u origin <tên-branch> để thiết lập quan hệ upstream này.

Sân chơi tương tác: Demo Diverge & Sync Giữa Local Và Remote

Kịch bản khởi đầu: bạn đã commit 1 thay đổi cục bộ, nhưng chưa fetch — trong lúc đó 1 đồng nghiệp đã âm thầm push 1 commit khác lên remote. Hãy thử git push ngay xem điều gì xảy ra, rồi git fetch, rồi thử cả git pull lẫn git pull --rebase (reset demo giữa 2 lần thử) để so sánh kết quả.

🌐 Sân chơi tương tác: Remote Sync Simulator

Terminal giả lập (local)

  • git commit -m "..."
  • git fetch
  • git pull
  • git pull --rebase
  • git push
  • git log

Nhật ký

git-remote-live.js

Trắc nghiệm ôn tập

Câu 1: Sau khi chạy git fetch, điều gì chắc chắn KHÔNG thay đổi?

Trắc nghiệm ôn tập

Câu 2: Vì sao git push đôi khi bị từ chối với lỗi "non-fast-forward"?

Trắc nghiệm ôn tập

Câu 3: Pull Request (GitHub) hay Merge Request (GitLab) có phải là 1 khái niệm cốt lõi của Git không?

📖 Tài liệu tham khảo / References

Bài viết liên quan trong series

Bài 10: Subtree & Submodule Bài 8: Git Bisect — Tìm Commit Lỗi Quay lại Lộ trình Series Git