Tổng quan và git remote

Xem thử

Vấn đề cần giải quyết

Bạn chạy git status và thấy "Your branch is up to date with 'origin/main'". Nhưng đồng đội vừa nhắn rằng họ đã push từ sáng. Bạn tự hỏi: vì sao Git bảo up to date mà máy chủ rõ ràng đã có thứ mới? Câu trả lời nằm ở chỗ origin/main không phải nhánh trên máy chủ, mà là một bản ghi nằm trong máy bạn.

Sau bài này, bạn có thể

  • Quản lý các kho từ xa bằng git remote: xem, thêm, đổi tên, xóa.
  • Phân biệt nhánh cục bộ, nhánh theo dõi (remote-tracking) và nhánh thật trên máy chủ.
  • Giải thích hai remote origin và upstream khi làm việc với fork.

Tiên quyết: chương Kiểm tra kho và khái niệm nhánh.

git remote

Git là hệ thống phân tán: bạn làm việc trên kho cục bộ rồi trao đổi commit với các kho từ xa (remote). Bốn lệnh chủ đạo là git remote, git fetch, git push và git pull.

bash
git remote -v
git remote add origin git@github.com:u/r.git
git remote rename origin upstream
git remote remove upstream
git remote show origin

Lệnh lần lượt xem danh sách remote, thêm remote tên origin, đổi tên, xóa và xem chi tiết.

Cách đọc hình. Khung bên trái là máy của bạn. main là nhánh cục bộ bạn commit vào. origin/main nằm ngay bên cạnh nhưng là remote-tracking branch: ảnh chụp trạng thái nhánh main trên máy chủ ở lần fetch gần nhất, chỉ đọc. Mũi tên đứt nét tới máy chủ cho thấy nó chỉ phản ánh trạng thái cũ của main thật.

Dễ nhầm: origin/main không phải nhánh main trên máy chủ; nó là bản ghi trong máy bạn và chỉ git fetch mới làm nó mới.

Thử và quan sát

Hãy dự đoán: đồng đội vừa push commit mới lên máy chủ. Máy bạn chạy git status ngay sau đó. Nó có báo bạn đang tụt lại phía sau không? Chạy mô phỏng và theo dõi origin/main qua từng bước. Biến thể cho thấy cách thêm remote thứ hai tên upstream.

Đang tải Animation…

Bảng bước (bản đọc tĩnh của mô phỏng)

BướcLệnhĐiều xảy ra
1(đồng đội) git push origin mainĐồng đội đẩy commit C4 lên máy chủ. Máy chủ đã đi trước, nhưng máy bạn chưa được thông báo gì.
2git statusGit vẫn báo up to date, vì nó so main với origin/main đã cũ trong máy bạn chứ không hỏi máy chủ.
3git fetchFetch hỏi máy chủ, tải C4 về và dời origin/main tới C4. Nhánh main của bạn vẫn đứng yên.
4git statusBây giờ origin/main đã mới, nên Git mới báo bạn đang tụt lại phía sau.

Biến thể: Thêm remote upstream

BướcLệnhĐiều xảy ra
1git remote add upstream git@github.com:org/app.gitThêm remote thứ hai trỏ tới kho gốc của dự án mà bạn đã fork.
2git fetch upstreamFetch từ upstream tạo thêm nhánh theo dõi upstream/main. Nhánh main của bạn vẫn không đổi.
3git remote -vMỗi remote hiện hai dòng, một cho fetch và một cho push. origin là nơi bạn push, upstream là nơi lấy cập nhật.

Giải đáp. Không. git status so main với origin/main đang có trong máy bạn, nên nó vẫn báo up to date cho tới khi bạn git fetch. Sau fetch, origin/main dời tới C4 và Git mới báo bạn đang tụt lại một commit.

origin và upstream

Cách đọc hình. Khi bạn fork một dự án, bạn có origin là bản fork của riêng bạn trên máy chủ và upstream là kho gốc. Bạn clone origin về máy, rồi tự thêm remote upstream bằng git remote add upstream <url> để lấy cập nhật. origin là nơi bạn push, upstream là nơi bạn lấy cập nhật.

Liệt kê nhánh theo dõi

bash
git branch -r
git branch -a

-r liệt kê nhánh theo dõi (như origin/main); -a liệt kê cả nhánh cục bộ lẫn nhánh theo dõi.

Hiểu lầm thường gặp

  • "origin/main là nhánh main trên server." Không, nó là ảnh chụp trong máy bạn, cập nhật khi fetch.
  • "origin là tên bắt buộc." Chỉ là tên mặc định khi clone; bạn đổi được và có thể có nhiều remote.
  • "up to date nghĩa là máy chủ không có gì mới." Nó chỉ nghĩa là bạn đã khớp với lần fetch gần nhất.

Tự kiểm tra

  1. Vì sao git status có thể báo up to date trong khi máy chủ đã có commit mới?
  2. Lệnh nào liệt kê các remote cùng URL?
  3. Khi fork một dự án, remote nào dùng để push và remote nào dùng để lấy cập nhật?

Đáp án gợi ý. (1) Nó so với origin/main cũ trong máy bạn chứ không hỏi máy chủ. (2) git remote -v. (3) origin để push; upstream để lấy cập nhật.

Điều cần nhớ

  • Remote-tracking branch là ảnh chụp trong máy bạn; chỉ fetch mới cập nhật.
  • git remote quản lý kết nối; có thể có nhiều remote.
  • origin là nơi push, upstream là nơi lấy cập nhật khi fork.
  • Bài sau: git fetch, tải về mà không đụng nhánh làm việc.

Nguồn tham khảo

Pro Git, chương 2.5 "Working with Remotes" và 3.5 "Remote Branches" (git-scm.com/book).