Tuần 1 - Ngày 4: Remote Repository — Làm Việc với Team
Mục tiêu học tập
- Cấu hình và quản lý remote với
git remote - Phân biệt
fetch,pull,pushvà khi nào dùng cái nào - Hiểu tracking branches và upstream
- Nắm rõ
pull --rebasevspullmặc định - Biết khi nào dùng
--force-with-leasethay vì--force
1. Remote là gì?
Remote là tên đặt cho URL của một repository khác — thường là GitHub, GitLab, hoặc Bitbucket. Khi clone, Git tự động tạo remote tên origin.
2. Quản lý remotes
# Xem các remotes đã cấu hình
git remote -v
# origin https://github.com/user/repo.git (fetch)
# origin https://github.com/user/repo.git (push)
# Thêm remote
git remote add origin https://github.com/user/repo.git
git remote add upstream https://github.com/original/repo.git
# Đổi URL remote (ví dụ: chuyển từ HTTPS sang SSH)
git remote set-url origin git@github.com:user/repo.git
# Xoá remote
git remote remove upstream
# Đổi tên remote
git remote rename origin github
# Xem chi tiết một remote
git remote show origin
3. git fetch — Tải về nhưng không merge
# Fetch tất cả branches từ origin
git fetch origin
# Fetch branch cụ thể
git fetch origin main
# Fetch tất cả remotes
git fetch --all
# Fetch và xoá remote-tracking branches đã bị xoá trên remote
git fetch --prune origin
# hoặc cấu hình auto-prune
git config --global fetch.prune true
Sau git fetch:
- Remote-tracking branches (
origin/main) được cập nhật - Branches local của bạn không thay đổi
- Bạn có thể xem diff trước khi merge:
git diff main origin/main
# Sau fetch, xem remote main khác local main thế nào
git fetch origin
git log main..origin/main --oneline # commits trên remote chưa có local
git log origin/main..main --oneline # commits local chưa push lên remote
git diff main origin/main # xem full diff
4. git push — Đẩy lên remote
# Push branch hiện tại lên remote, set upstream
git push -u origin main
git push -u origin feature/auth
# -u = --set-upstream: lần sau chỉ cần gõ git push
# Push sau khi đã set upstream
git push
# Push và xoá branch remote
git push origin --delete feature/old-branch
# Push tag
git push origin v1.0.0
git push origin --tags # push tất cả tags
# Push tất cả branches (ít dùng)
git push --all origin
--force-with-lease — Cách push an toàn hơn --force
# Tình huống: bạn đã rebase và cần push lên remote branch
# (remote branch và local không còn cùng history)
# NGUY HIỂM: --force ghi đè không kiểm tra
git push --force origin feature/auth
# Nếu đồng nghiệp push trong lúc bạn đang rebase → commits của họ bị mất!
# AN TOÀN HƠN: --force-with-lease
git push --force-with-lease origin feature/auth
# Git kiểm tra: remote-tracking ref (origin/feature/auth) có khớp với
# remote thực không? Nếu ai push trước → Git từ chối, bạn phải fetch trước
# Quy tắc:
# - KHÔNG BAO GIỜ force push lên main/master/develop (shared branches)
# - force-with-lease chỉ dùng trên PERSONAL branches (feature/ branches)
# - Sau rebase cá nhân → force-with-lease
5. git pull — Fetch + merge
git pull là shortcut cho git fetch + git merge (hoặc git rebase).
# Pull mặc định = fetch + merge
git pull origin main
git pull # nếu đã set upstream
# Pull với rebase thay vì merge
git pull --rebase origin main
git pull --rebase
# Xem sẽ pull gì trước khi pull
git fetch && git log ..origin/main --oneline
pull mặc định vs pull --rebase
Khi nào dùng --rebase?
# Dùng --rebase khi:
# - Làm việc một mình trên feature branch
# - Muốn lịch sử tuyến tính (không có merge commits vô nghĩa)
# - CI/CD yêu cầu linear history
# Cấu hình mặc định pull --rebase
git config --global pull.rebase true
# Hoặc chỉ cho repo hiện tại
git config pull.rebase true
# Dùng merge khi:
# - Muốn lưu lại context "merge từ upstream vào feature branch"
# - Branch shared (nhiều người cùng push)
6. Tracking Branches
Tracking branch là liên kết giữa local branch và remote branch. Khi set tracking, git push/git pull biết remote nào và branch nào để sync.
# Khi clone, main tự động track origin/main
# Set upstream khi push lần đầu
git push -u origin feature/auth
# Sau đó: git push và git pull hoạt động không cần chỉ định
# Xem tracking info
git branch -vv
# main abc1234 [origin/main] feat: add user login
# feature/auth def5678 [origin/feature/auth: ahead 2] feat: auth WIP
# Set tracking cho branch đã tồn tại
git branch --set-upstream-to=origin/feature/auth feature/auth
# hoặc ngắn hơn
git branch -u origin/feature/auth
# Tạo local branch track remote branch
git switch --track origin/feature/auth
# tạo local feature/auth tracking origin/feature/auth
7. Workflow với remote thực tế
Bắt đầu feature mới
# 1. Sync main trước
git switch main
git pull --rebase origin main
# 2. Tạo branch
git switch -c feature/payment-gateway
# 3. Làm việc, commit
git add . && git commit -m "feat: add Stripe integration"
# 4. Push lần đầu với -u
git push -u origin feature/payment-gateway
# 5. Push tiếp theo
git push
# 6. Sau khi PR merge, dọn dẹp
git switch main
git pull
git branch -d feature/payment-gateway
git push origin --delete feature/payment-gateway
Nhận thay đổi của đồng đội
# Đồng nghiệp đã merge PR vào main
git switch main
git fetch origin
git log ..origin/main --oneline # xem có gì mới
git merge origin/main # hoặc git pull
# Cập nhật feature branch của bạn sau khi main có thay đổi
git switch feature/my-feature
git rebase main # rebase lên main mới nhất
Câu hỏi ôn tập
-
git fetchvàgit pullkhác nhau ở bước nào?Xem đáp án
git fetchchỉ tải về remote objects và cập nhật remote-tracking branches (origin/main...) — không thay đổi local branches.git pull=git fetch+git merge(hoặcgit rebase). Fetch cho phép xem sự khác biệt (git diff main origin/main) trước khi quyết định merge — an toàn hơn khi làm việc trên shared branches. -
Tracking branch là gì? Lợi ích của nó?
Xem đáp án
Tracking branch là liên kết giữa local branch và remote branch tương ứng (upstream). Set khi dùng
git push -u origin feature/xhoặcgit switch --track origin/feature/x. Lợi ích: sau khi set, chỉ cần gõgit pushvàgit pullmà không cần chỉ định remote/branch.git branch -vvhiển thị tracking info và số commits ahead/behind. -
Tại sao
--force-with-leasean toàn hơn--force?Xem đáp án
--forceghi đè remote branch bất kể có ai push thêm gì không.--force-with-leasekiểm tra remote-tracking ref local (origin/feature/x) có khớp với remote thực hay không trước khi push. Nếu đồng nghiệp đã push lên branch đó trong lúc bạn đang rebase → Git từ chối, bảo vệ commits của họ. Luôn dùng--force-with-leasetrên feature branches cá nhân. -
git pull --rebasetạo ra lịch sử khác gì so vớigit pullmặc định?Xem đáp án
git pullmặc định (merge) tạo một merge commit khi cả hai branches đều có commits riêng — lịch sử có nhánh rẽ.git pull --rebaseđặt commits local của bạn lên trên commits remote, tạo lịch sử tuyến tính không có merge commit thừa. Phù hợp hơn cho feature branches cá nhân; cấu hình global bằnggit config --global pull.rebase true. -
Khi chạy
git pushmà Git báoThe current branch has no upstream branch, phải làm gì?Xem đáp án
Branch chưa được set tracking upstream. Chạy
git push -u origin <tên-branch>để push lên remote và set upstream cùng lúc. Sau đógit pushvàgit pullsẽ hoạt động mà không cần chỉ định thêm. Có thể cấu hình auto-setup:git config --global push.autoSetupRemote trueđể không cần gõ-umỗi lần.
Bài tập thực hành
# Cần có GitHub account để thực hành bài này
# 1. Tạo repo trên GitHub, sau đó clone
git clone https://github.com/YOUR_USER/test-repo.git
cd test-repo
# 2. Xem remote đã được cấu hình tự động
git remote -v
# 3. Tạo file và push
echo "# Test" > README.md
git add README.md
git commit -m "docs: add README"
git push -u origin main # set upstream lần đầu
# 4. Trên GitHub: tạo một file qua UI (simulate đồng đội push)
# 5. Fetch về xem
git fetch origin
git log ..origin/main --oneline # thấy commit từ GitHub
# 6. Merge
git merge origin/main
git log --oneline
# 7. Tạo feature branch và push
git switch -c feature/test
echo "feature content" > feature.txt
git add feature.txt && git commit -m "feat: test feature"
git push -u origin feature/test
# 8. Xem tracking
git branch -vv
Tài liệu tham khảo chính thức
Tiếp theo: Ngày 5 — Merge vs Rebase