Lập trình · 19/09/2026

Git worktree thực chiến: Làm nhiều nhánh song song không cần stash

Bạn đang sửa một tính năng dở dang thì production cần hotfix ngay. Cách quen thuộc là stash thay đổi, chuyển nhánh, sửa lỗi rồi quay lại. Nhưng khi workspace có nhiều file chưa commit, dependency đang chạy và IDE đã mở đúng ngữ cảnh, chuỗi thao tác đó vừa mất thời gian vừa dễ nhầm. git worktree giải quyết bài toán bằng cách cho một repository có nhiều thư mục làm việc, mỗi thư mục checkout một nhánh riêng.

Git worktree thực chiến: Làm nhiều nhánh song song không cần stash

Bạn đang sửa một tính năng dở dang thì production cần hotfix ngay. Cách quen thuộc là stash thay đổi, chuyển nhánh, sửa lỗi rồi quay lại. Nhưng khi workspace có nhiều file chưa commit, dependency đang chạy và IDE đã mở đúng ngữ cảnh, chuỗi thao tác đó vừa mất thời gian vừa dễ nhầm. git worktree giải quyết bài toán bằng cách cho một repository có nhiều thư mục làm việc, mỗi thư mục checkout một nhánh riêng.

Git worktree là gì?

Một repository thông thường có một working tree: thư mục chứa source code bạn đang chỉnh sửa. Git worktree cho phép gắn thêm các linked worktree vào cùng repository. Chúng dùng chung object database và lịch sử Git, nhưng mỗi nơi có HEAD, index và file làm việc riêng.

Vì dùng chung dữ liệu Git, worktree nhẹ hơn clone lại toàn bộ repository. Commit tạo ở worktree feature xuất hiện ngay trong repository chính; bạn không cần fetch giữa các thư mục trên cùng máy.

Worktree không phải bản sao tạm thời. Mỗi worktree là một workspace Git thực thụ, có branch và trạng thái file độc lập.

Khi nào nên dùng?

  • Đang làm feature dài ngày nhưng cần xử lý hotfix khẩn cấp.
  • Muốn chạy hai phiên bản ứng dụng cạnh nhau để so sánh hành vi.
  • Review pull request mà không làm xáo trộn nhánh đang phát triển.
  • Chạy test hoặc migration trên một nhánh trong khi vẫn viết code ở nhánh khác.
  • Làm việc với nhiều tác vụ hoặc coding agent song song, mỗi tác vụ có workspace riêng.

Nếu chỉ cần xem nhanh một file cũ hoặc đổi nhánh khi workspace đang sạch, git switch vẫn đơn giản hơn. Worktree phát huy giá trị khi các ngữ cảnh cần tồn tại đồng thời.

1. Tạo worktree cho một feature mới

Giả sử repository chính nằm trong thư mục shop và đang ở nhánh main:

cd shop
git fetch origin
git worktree add -b feature/checkout ../shop-checkout origin/main

Lệnh trên tạo nhánh feature/checkout từ origin/main, đồng thời checkout nhánh đó vào thư mục ngang cấp shop-checkout. Sau đó mở IDE hoặc terminal mới:

cd ../shop-checkout
git status
git branch --show-current

Mọi commit trong thư mục này thuộc nhánh feature. Repository chính vẫn giữ nguyên branch và toàn bộ thay đổi chưa commit ban đầu.

2. Tạo hotfix trong lúc feature còn dang dở

git fetch origin
git worktree add -b hotfix/payment-timeout ../shop-hotfix origin/main

cd ../shop-hotfix
# sửa lỗi, chạy test
git add .
git commit -m "Fix payment timeout handling"
git push -u origin hotfix/payment-timeout

Feature không cần stash và dev server của feature có thể tiếp tục chạy. Sau khi hotfix được merge, xóa worktree đúng cách:

cd ../shop
git worktree remove ../shop-hotfix
git branch -d hotfix/payment-timeout

worktree remove chỉ xóa worktree sạch. Nếu còn file sửa hoặc file chưa được theo dõi, Git sẽ từ chối để bảo vệ dữ liệu. Hãy kiểm tra và commit hoặc sao lưu phần cần thiết trước khi cân nhắc --force.

3. Checkout một nhánh đã tồn tại

git fetch origin
git worktree add ../shop-release release/2.4

Một branch thông thường không thể được checkout đồng thời ở hai worktree. Ràng buộc này ngăn hai thư mục cùng âm thầm thay đổi một branch. Nếu nhánh đang được dùng, git worktree list cho biết nó nằm ở đâu.

Để xem một commit mà không gắn với branch, chẳng hạn phục vụ điều tra hoặc benchmark, dùng detached HEAD:

git worktree add --detach ../shop-benchmark v2.3.1

Nếu cần giữ commit tạo trong chế độ detached, hãy tạo branch trước khi dọn worktree.

4. Quản lý danh sách worktree

git worktree list
git worktree list --porcelain

Dạng mặc định phù hợp cho con người; --porcelain có định dạng ổn định để script xử lý. Không nên tự đọc hoặc chỉnh các file quản trị trong .git/worktrees.

Một quy ước thư mục dễ quản lý là đặt linked worktree cạnh repository chính:

projects/
├── shop/              # main worktree
├── shop-feature-cart/
├── shop-hotfix-auth/
└── shop-review-482/

Tên thư mục nên thể hiện mục đích và số issue/PR. Không đặt worktree bên trong repository chính vì công cụ tìm kiếm, watcher hoặc Docker build context có thể quét lẫn source của nhánh khác.

5. Dependency, biến môi trường và cổng dịch vụ

Các worktree chia sẻ Git object nhưng không chia sẻ file bị ignore. Mỗi thư mục thường cần cài dependency riêng như node_modules, vendor hoặc virtual environment. Đây là điều tốt về tính cô lập nhưng tốn thêm dung lượng.

  • Tạo .env riêng cho từng worktree và không commit secret.
  • Dùng database/schema hoặc container name khác nếu hai phiên bản chạy đồng thời.
  • Đặt port khác nhau, ví dụ ứng dụng chính ở 3000 và feature ở 3001.
  • Không dùng chung thư mục build/cache nếu công cụ không bảo đảm concurrency.

Có thể viết script bootstrap của dự án để copy .env.example, cài dependency và in ra port đề xuất ngay sau khi tạo worktree.

6. Di chuyển, khóa và sửa worktree

Muốn đổi vị trí linked worktree, ưu tiên lệnh Git thay vì kéo thả thư mục:

git worktree move ../shop-feature-cart ../archive/shop-cart

Nếu worktree nằm trên ổ rời hoặc network share đôi khi không được mount, hãy khóa để metadata không bị dọn:

git worktree lock --reason "External SSD" ../archive/shop-cart
git worktree unlock ../archive/shop-cart

Nếu bạn đã di chuyển thư mục thủ công hoặc đường dẫn repository chính thay đổi, dùng:

git worktree repair ../archive/shop-cart

Worktree có submodule có thêm giới hạn khi move/remove; luôn kiểm tra phiên bản Git và tài liệu hiện hành trước khi tự động hóa quy trình này.

7. Dọn metadata bị sót

Nếu ai đó xóa thẳng thư mục linked worktree, metadata có thể còn lại. Hãy xem trước rồi mới dọn:

git worktree prune --dry-run --verbose
git worktree prune --verbose

prune dọn thông tin của worktree không còn tồn tại; nó không phải lệnh dọn branch đã merge. Việc xóa branch vẫn thực hiện riêng bằng git branch -d.

8. Workflow review pull request an toàn

git fetch origin pull/482/head:review/pr-482
git worktree add ../shop-review-482 review/pr-482

cd ../shop-review-482
# cài dependency, chạy test, đọc code

Khi review xong:

cd ../shop
git worktree remove ../shop-review-482
git branch -D review/pr-482

Workflow này giữ nguyên workspace feature và giúp review đúng code thực tế. Với nền tảng không cung cấp ref pull/.../head, fetch branch remote tương ứng rồi tạo worktree từ remote-tracking branch.

9. Những lỗi thường gặp

  • “branch is already checked out”: branch đang nằm trong worktree khác; xem git worktree list thay vì ép checkout.
  • Xóa thư mục bằng trình quản lý file: dùng git worktree remove để dọn cả thư mục lẫn metadata.
  • Nhầm rằng stash dùng chung theo workspace: stash thuộc repository chung, nên nội dung stash có thể nhìn thấy từ mọi worktree.
  • Hai server tranh cùng port: cấp port, database và tên container riêng.
  • Force remove khi chưa kiểm tra: có thể mất file untracked; luôn chạy git status trong đúng worktree.
  • Tạo quá nhiều worktree bỏ quên: định kỳ xem danh sách, tuổi branch và trạng thái PR.

Checklist áp dụng cho đội nhóm

  1. Đặt linked worktree ngoài thư mục repository chính.
  2. Mỗi task dùng một branch và một worktree rõ tên.
  3. Tách port, database, cache và biến môi trường khi chạy song song.
  4. Commit hoặc lưu dữ liệu cần thiết trước khi remove.
  5. Dùng remove, moverepair thay cho thao tác file thủ công.
  6. Dọn worktree sau khi PR merge và xóa branch theo chính sách của đội.

Kết luận

git worktree không thay thế branch, commit hay stash; nó bổ sung khả năng giữ nhiều ngữ cảnh làm việc cùng lúc. Với feature dài ngày, hotfix khẩn cấp và review song song, worktree giúp giảm chuyển đổi ngữ cảnh mà vẫn dựa trên cơ chế bảo vệ dữ liệu của Git. Hãy bắt đầu bằng một worktree hotfix nhỏ, đặt quy ước thư mục rõ ràng và dọn nó ngay khi công việc hoàn tất.

Tài liệu tham khảo

Thảo luận

Bình luận 0

Đăng nhập để bình luận

Bạn cần có tài khoản để tham gia thảo luận và trả lời độc giả khác.

Đăng nhậpĐăng ký

Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.