Git worktree là gì? Hướng dẫn các lệnh worktree qua ví dụ thực tế
Giữa lúc đang code dở một feature mà cần hotfix production — bạn sẽ stash, hay clone thêm một bản? Git worktree là câu trả lời gọn hơn cả hai: nhiều branch, nhiều thư mục, vẫn một repository duy nhất.

Git worktree là gì?
Git worktree là tính năng built-in của Git (ra mắt từ Git 2.5, năm 2015) cho phép gắn thêm nhiều working tree vào cùng một repository — nghĩa là bạn checkout được nhiều branch cùng lúc, mỗi branch nằm ở một thư mục riêng trên ổ đĩa.
Cách hiểu đơn giản:
- Repository của bạn có một main worktree — chính là thư mục bạn
git clonevề, nơi cógit init. - Mỗi
git worktree addtạo ra một linked worktree — một thư mục mới, trỏ về cùng kho dữ liệu.git/của repository gốc. - Tất cả worktree chia sẻ chung object store và lịch sử commit. Không tiêu tốn nhân đôi dung lượng ổ cứng như khi clone nhiều lần.
Điều duy nhất không chia sẻ là các file trạng thái riêng của từng worktree: HEAD, index, thư mục làm việc. Vì thế mỗi worktree checkout được một branch khác nhau mà không trùng lắp lẫn lộn vào nhau.
Khi nào nên dùng git worktree?
Worktree giải quyết những tình huống rất cụ thể:
| Tình huống | Cách cũ | Dùng worktree |
|---|---|---|
| Đang code dở feature, cần hotfix production ngay | git stash → switch → fix → switch lại → stash pop (dễ conflict) | Mở worktree mới cho hotfix/*, code feature vẫn nguyên vẹn |
| Build/test nhiều branch song song | Clone nhiều bản, mỗi bản vài GB | Nhiều worktree, dùng chung .git, tiết kiệm dung lượng |
| So sánh hành vi hai branch | Liên tục git switch qua lại, mất context | Hai thư mục mở cạnh nhau, so sánh trực tiếp |
| Chạy nhiều AI agent cùng lúc trên một repo | Chạy chung một thư mục → ghi đè file của nhau | Mỗi agent một worktree, một branch, hoàn toàn cô lập |
Ví dụ thực tế
Giả sử bạn đang có project tại ~/projects/myapp và đang code nhánh feature/login cho tính năng đăng nhập. Bỗng production báo lỗi, cần fix gấp trên main (nhánh triển khai production của dự án).
Bước 0 — Kiểm tra hiện trạng
$ cd ~/projects/myapp
$ git worktree list
/home/minhng/projects/myapp a1b2c3d4 [feature/login]
Lúc này chỉ có đúng một worktree — thư mục gốc, đang ở branch feature/login. Đây là điểm khởi đầu.
Bước 1 — Tạo worktree cho hotfix
$ git worktree add -b hotfix/login-crash ../myapp-hotfix main
Đọc lệnh này theo từng phần:
| Thành phần | Ý nghĩa |
|---|---|
worktree add | Tạo một linked worktree mới |
-b hotfix/login-crash | Tạo branch mới tên hotfix/login-crash và checkout luôn |
../myapp-hotfix | Đường dẫn đặt worktree mới (thư mục cùng cấp, nằm ngoài repo gốc) |
main | Điểm xuất phát — branch/commit mà branch mới rẽ ra từ đó |
Kết quả: một thư mục ~/projects/myapp-hotfix xuất hiện, chứa đúng nội dung của main, còn thư mục gốc vẫn đang ở feature/login — code dở của bạn không bị ảnh hưởng gì.
$ cd ../myapp-hotfix
$ git status
On branch hotfix/login-crash
$ # code fix, commit...
$ git commit -am "fix: crash when login session expired"
Các biến thể add hay dùng:
# Làm việc trên branch ĐÃ CÓ ở một worktree khác
$ git worktree add ../myapp-review feature/login
# Tạo thư mục tạm để thử nghiệm, không gắn branch nào (detached HEAD)
$ git worktree add -d ../myapp-scratch
# Đặt tên branch trùng tên thư mục (branch "hotfix" được tạo tự động)
$ git worktree add ../hotfix
Git sẽ từ chối tạo worktree nếu branch đó đang được checkout ở một worktree khác. Một branch chỉ được có một worktree hoạt động tại một thời điểm.
Bước 2 — Xem danh sách worktree
$ git worktree list
/home/minhng/projects/myapp a1b2c3d4 [feature/login]
/home/minhng/projects/myapp-hotfix e5f6a7b8 [hotfix/login-crash]
- Worktree đầu tiên luôn là main worktree.
- Muốn xem chi tiết hơn (có thêm commit hash đầy đủ):
git worktree list -v. - Cần đọc bằng script/CI:
git worktree list --porcelain— định dạng ổn định, machine-readable.
Ngoài ra còn 2 trạng thái đáng chú ý trong output: locked (worktree bị khoá) và prunable (đã mất thư mục, có thể dọn).
Bước 3 — Dọn dẹp worktree
Sau khi merge xong hotfix:
$ git worktree remove ../myapp-hotfix
Quy tắc cần nhớ:
- Chỉ xoá được worktree sạch — không có file untracked, không có thay đổi chưa commit.
- Có thay đổi dở dang → dùng
git worktree remove --force ../myapp-hotfix. - Không thể xoá main worktree.
removechỉ xoá thư mục worktree, không xoá branch. Muốn xoá branch phải chạy riêng:git branch -d hotfix/login-crash.
Bước 4 — Nếu bạn lỡ tay xoá thư mục worktree
Chuyện rất hay xảy ra: bạn rm -rf thư mục worktree bằng tay thay vì dùng remove. Git vẫn giữ lại hồ sơ quản lý worktree đó trong .git/worktrees/, gây rác.
# Xem trước những gì sẽ bị dọn (không xoá thật)
$ git worktree prune -n -v
# Dọn thật
$ git worktree prune
prune sẽ xoá phần metadata của những worktree có thư mục đã biến mất. Bạn cũng có thể dùng --expire để chỉ dọn entry cũ hơn một mốc thời gian.
Các lệnh nâng cao (dùng khi có sự cố)
Phần lớn thời gian bạn chỉ cần 4 lệnh ở trên. Bốn lệnh dưới đây dùng cho các tình huống trục trặc kỹ thuật:
git worktree lock / unlock — khoá worktree
Khi worktree nằm trên ổ di động hoặc network share không phải lúc nào cũng mount, Git có thể tưởng nó đã mất và dọn mất metadata. lock ngăn điều đó:
$ git worktree lock ../myapp-usb --reason "worktree on USB drive"
$ git worktree unlock ../myapp-usb
Worktree bị lock cũng không thể bị move hay xoá, ngăn việc git tự mất metadata của worktree này.
git worktree move — di chuyển worktree
$ git worktree move ../myapp-hotfix /data/worktrees/myapp-hotfix
Lưu ý: main worktree và worktree có chứa submodule không di chuyển được bằng lệnh này.
git worktree repair — sửa liên kết bị gãy
Nếu bạn di chuyển hoặc copy thư mục bằng tay (Finder, File Explorer, mv), liên kết giữa worktree và .git sẽ đứt. repair nối lại:
# Chạy trong main worktree để nối lại các linked worktree bị lệch
$ git worktree repair
# Hoặc chạy trong worktree vừa bị di chuyển
$ cd /new/location/myapp-hotfix
$ git worktree repair
Đừng bao giờ di chuyển thư mục worktree bằng tay
mv, hãy dùng lệnh gitgit worktree move.
Bảng tổng hợp lệnh worktree
| Lệnh | Tác dụng |
|---|---|
git worktree add <path> <branch> | Tạo worktree mới từ branch/commit có sẵn |
git worktree add -b <new-branch> <path> <base> | Tạo branch mới + worktree từ <base> |
git worktree add -d <path> | Worktree tạm, detached HEAD, không gắn branch |
git worktree list | Liệt kê các worktree (-v chi tiết, --porcelain cho script) |
git worktree remove <path> | Xoá worktree (--force nếu còn thay đổi dở) |
git worktree prune | Dọn metadata của worktree đã mất thư mục |
git worktree lock / unlock | Khoá / mở khoá worktree |
git worktree move <path> <new-path> | Di chuyển worktree (trừ main & worktree có submodule) |
git worktree repair | Sửa liên kết bị gãy do di chuyển thủ công |
Những điều cần lưu ý
- Một branch — một worktree. Git chặn việc checkout cùng branch ở hai nơi để tránh xung đột trạng thái. Cần hai nơi cùng code thì tách branch ra.
- Đặt worktree ra ngoài thư mục repo. Ví dụ
../myapp-hotfixthay vì./hotfix. Đặt bên trong repo dễ khiến Git track nhầm toàn bộ file của worktree. - Nhớ dọn dẹp. Worktree không tự biến mất. Cuối mỗi đợt làm việc, chạy
git worktree listxem còn worktree nào thừa không. git worktree remove <path>không xoá branch, chỉ xóa worktree. Đây là hiểu nhầm phổ biến nhất — xoá branch phải chạygit branch -driêng.- Dung lượng: nhiều worktree dùng chung
.gitnên không bị tăng tiến về dung lượng lưu trữ lịch-sử-git, nhưng mỗi worktree vẫn có bản working files riêng — 10 worktree của một repo 2GB vẫn tốn ~20GB working files.
Tổng kết
Git worktree biến một repository thành nhiều không gian làm việc song song mà không phải clone đi clone lại. Với 4 lệnh add / list / remove / prune, bạn đã xử lý được 95% nhu cầu thực tế — đặc biệt là bài toán kinh điển. Trong kỷ nguyên AI, git worktree lại càng phát huy tính hữu dụng khi nó trở thành không gian làm việc cô lập của mỗi AI agent.
Tham khảo tài liệu chính thức: git-scm.com/docs/git-worktree

