Git Worktree: Làm việc trên nhiều branch cùng lúc mà không cần stash hay clone

Git tutorial - IT technology blog
Git tutorial - IT technology blog

Vấn đề quen thuộc: đang làm dở thì bị kéo sang việc khác

Bạn đang code feature mới trên branch feature/payment, chỉnh sửa được nửa chừng thì sếp nhắn: “Khẩn, khách hàng báo bug production, fix ngay đi”. Lúc này bạn có mấy lựa chọn:

  • Commit tạm (commit rác làm bẩn history)
  • Dùng git stash (rồi quên mất, tìm lại đau đầu)
  • Clone cả repo sang thư mục khác (tốn dung lượng, phải setup lại node_modules…)

Mình đã trải qua cả ba kiểu đó. Thậm chí có lần vừa stash vội vừa panic, rồi lại git push --force nhầm branch — mất đứt một buổi sáng code. Từ đó mình cực kỳ cẩn thận với force push, nhưng cũng bắt đầu tìm cách tốt hơn để xử lý tình huống context-switching kiểu này.

Và đó là lúc mình tìm ra Git Worktree.

Git Worktree là gì?

Worktree (hay working tree) là thư mục chứa các file bạn đang làm việc — cái folder bạn mở bằng VS Code hay terminal hàng ngày đó. Bình thường, một repo chỉ có một working tree.

Git Worktree cho phép bạn gắn thêm working tree phụ vào cùng một repo, mỗi tree checkout một branch khác nhau. Tất cả dùng chung một .git folder — chung history, chung object database — nhưng files làm việc thì tách biệt hoàn toàn.

Hình dung thế này: giống như mở cùng một Google Docs trên hai tab trình duyệt, mỗi tab đang ở một phiên bản khác nhau của document — nhưng dữ liệu gốc vẫn là một.

So sánh nhanh với các giải pháp khác

  • git stash: Lưu tạm được, nhưng phải switch branch và mất context. Dự án lớn stash cả chục lần là bắt đầu lẫn lộn.
  • Clone repo mới: Tốn dung lượng gấp đôi — project có node_modules 500MB thì nhân đôi ngay. Chưa kể phải cài lại dependencies từ đầu.
  • Git Worktree: Thư mục làm việc riêng, branch riêng, nhưng dùng chung .git — nhanh, gọn, không trùng lặp.

Thực hành: dùng Git Worktree như thế nào

1. Xem worktree hiện tại

Bất kỳ repo nào cũng có sẵn ít nhất một worktree — chính là thư mục bạn đang làm việc. Kiểm tra bằng lệnh:

git worktree list

Output sẽ trông như thế này:

/home/user/myproject  abc1234 [main]

2. Tạo worktree mới cho branch hotfix

Quay lại tình huống ban đầu: bạn đang ở feature/payment, cần fix bug trên main. Thay vì stash, bạn tạo một worktree mới:

# Tạo thư mục ../myproject-hotfix, checkout branch hotfix/critical-bug
git worktree add ../myproject-hotfix hotfix/critical-bug

Nếu branch chưa tồn tại, tạo luôn bằng flag -b:

git worktree add -b hotfix/critical-bug ../myproject-hotfix main

Lệnh này tạo branch mới hotfix/critical-bug từ main, checkout vào thư mục ../myproject-hotfix.

Giờ bạn mở thêm một terminal, cd ../myproject-hotfix và làm việc thoải mái — terminal cũ vẫn đứng yên ở feature/payment, không bị đụng đến.

3. Làm xong hotfix, dọn dẹp

Sau khi commit và push hotfix xong, xóa worktree phụ đi:

# Xóa worktree (thư mục sẽ bị xóa theo)
git worktree remove ../myproject-hotfix

# Hoặc nếu có file chưa commit muốn xóa ép:
git worktree remove --force ../myproject-hotfix

Sau đó dọn dẹp metadata thừa (nên chạy định kỳ):

git worktree prune

4. Workflow thực tế: review PR trong khi vẫn đang code

Đây là use case mình dùng nhiều nhất. Teammate gửi PR cần review, nhưng mình đang code dở. Thay vì stash hoặc commit rác:

# Tạo worktree để review PR #42
git worktree add ../review-pr-42 origin/feature/teammate-branch

# Mở thư mục đó trong editor khác hoặc terminal khác
code ../review-pr-42

Review xong, đóng editor, xóa worktree:

git worktree remove ../review-pr-42

5. Dùng với bare repo — cách setup chuyên nghiệp hơn

Nếu bạn thường xuyên làm việc multi-branch, có thể setup theo kiểu bare repo — clone không có working tree mặc định, rồi tạo worktree cho từng branch cần dùng:

# Clone dạng bare
git clone --bare https://github.com/user/myproject.git myproject.git
cd myproject.git

# Tạo worktree cho từng branch
git worktree add ../myproject-main main
git worktree add ../myproject-feature feature/payment
git worktree add ../myproject-staging staging

Kết quả bạn có cấu trúc như này:

myproject.git/          ← .git folder (bare)
myproject-main/         ← branch main
myproject-feature/      ← branch feature/payment
myproject-staging/      ← branch staging

Mỗi thư mục là một working tree độc lập. Mở terminal nào cũng không ảnh hưởng terminal kia.

Một số điều cần lưu ý

  • Một branch chỉ được checkout ở một worktree: nếu thử checkout main ở hai worktree cùng lúc, Git sẽ báo lỗi. Git làm vậy là có lý — tránh conflict khi hai process cùng ghi vào một branch.
  • Node modules, build artifacts không được chia sẻ: mỗi worktree là thư mục riêng, bạn phải npm install hoặc build lại cho từng cái nếu cần.
  • File .git trong worktree phụ là file (không phải folder): nó chứa đường dẫn trỏ về .git chính — đây là cách Git quản lý liên kết giữa các worktree.

Kết luận

Cái hay của Git Worktree là nó xử lý đúng tình huống developer nào cũng từng gặp: đang code dở thì bị kéo sang việc khác. Thay vì commit rác, stash rồi quên, hay clone thêm repo nặng nề — một lệnh là có ngay thư mục làm việc mới, sạch sẽ, đúng branch.

Thực tế, mình hay dùng nhất trong hai trường hợp: hotfix gấp và review PR. Cả hai đều xong trong vài giây setup, không phá vỡ context đang làm. Thử một lần rồi bạn sẽ thấy khó quay lại kiểu stash-rồi-tìm-stash cũ như trước.

Team nào đang dùng Git hàng ngày mà chưa biết Worktree thì đây là tính năng đáng học nhất trong năm — nhỏ, không cần cài thêm gì, nhưng tiết kiệm được kha khá thời gian và đau đầu.

Share: