Domain 4 · 9 phút đọc

Fetch, pull và push: đồng bộ với remote

Fetch, Pull and Push

Sau khi đã có remote, bạn cần ba thao tác để đồng bộ sync: fetch để tải về, pull để tải và gộp, push để gửi lên. Hiểu rõ chúng giúp bạn tránh các xung đột và lịch sử rối.

git fetch: chỉ tải về, không gộp

git fetch tải các commit mới từ remote về repo local, cập nhật các nhánh theo dõi remote (như origin/main), nhưng không đụng tới nhánh đang làm việc của bạn.

# Tải mọi cập nhật từ origin, không thay đổi nhánh hiện tại
git fetch origin

Sau khi fetch, bạn có thể xem trước thay đổi trước khi quyết định gộp:

# So sánh nhánh local với nhánh remote vừa fetch về
git log main..origin/main --oneline

Vì fetch an toàn (không tự sửa code đang làm), nó là cách tốt để xem người khác đã đẩy gì lên trước khi gộp.

git pull: fetch rồi merge

git pull thực chất là hai bước gộp một: git fetch rồi git merge. Nó tải về và ngay lập tức gộp nhánh remote vào nhánh hiện tại.

# Tương đương: git fetch origin + git merge origin/main
git pull origin main

Nếu nhánh của bạn và remote đã phân nhánh (cả hai cùng có commit mới), pull tạo một merge commit để gộp. Nếu có xung đột nội dung, Git dừng lại để bạn giải quyết.

git push: đẩy commit lên remote

git push gửi các commit local của bạn lên remote.

# Đẩy nhánh main local lên origin
git push origin main

Git từ chối push nếu remote có commit mà bạn chưa có (non-fast-forward) để tránh ghi đè mất việc của người khác. Khi đó bạn phải pull (hoặc pull --rebase) để gộp về trước, rồi push lại.

Tránh git push --force

git push --force ghi đè lịch sử remote và có thể xóa mất commit của đồng đội. Chỉ dùng trên nhánh riêng của bạn, và ưu tiên --force-with-lease an toàn hơn vì nó kiểm tra remote chưa thay đổi ngoài dự kiến.

pull --rebase: lịch sử thẳng hàng

git pull --rebase thay vì tạo merge commit, sẽ rebase các commit local của bạn lên trên commit mới nhất của remote. Kết quả là lịch sử thẳng, không có merge commit thừa.

# Fetch rồi rebase commit local lên trên origin/main
git pull --rebase origin main
Tiêu chígit pull (merge)git pull --rebase
Tạo merge commitCó (khi phân nhánh)Không
Hình dạng lịch sửCó nhánh, có gộpThẳng, tuyến tính
Giữ nguyên hash commitKhông (viết lại)
Hợp với nhánh đã chia sẻAn toàn hơnCẩn thận với nhánh chung

Đặt rebase làm mặc định

Nhiều đội đặt git config --global pull.rebase true để mọi git pull mặc định rebase, cho lịch sử gọn. Nhưng tránh rebase commit đã được push và người khác đã pull về.

Trọng tâm thi

git fetch chỉ tải về (cập nhật origin/main), không đụng nhánh local. git pull = fetch + merge (gộp ngay). git pull --rebase = fetch + rebase cho lịch sử thẳng. git push bị từ chối nếu non-fast-forward — phải pull về trước.

Tóm tắt

  • git fetch: tải commit mới về, cập nhật nhánh remote (origin/main), không sửa nhánh đang làm.
  • git pull: fetch rồi merge — tải và gộp ngay vào nhánh hiện tại, có thể tạo merge commit.
  • git push: đẩy commit local lên remote; bị từ chối nếu remote có commit bạn chưa có.
  • git pull --rebase: fetch rồi rebase, cho lịch sử thẳng, không merge commit thừa.
  • Tránh push --force trên nhánh chung; nếu cần thì ưu tiên --force-with-lease.