Worktree rất dễ tạo và cũng rất dễ quên. Bạn tạo một cái để agent làm việc trên một nhánh một cách tách biệt, agent làm xong, bạn review diff, rồi thư mục cứ nằm đó. Một tuần sau, git worktree list dài đến mức trôi khỏi màn hình, du -sh trên repo báo mười hai gigabyte, và ba trong số những thư mục đó trỏ tới các nhánh đã được merge rồi xóa từ mấy ngày trước. Không ai chủ ý giữ chúng lại. Chúng cứ tích tụ, vì tạo thì chỉ một câu lệnh, còn dọn dẹp lại là một mối phiền.
Đây chính là phần của công việc agent song song mà không ai cảnh báo bạn. Cơ chế tách biệt (isolation) thì đã được ghi chép đầy đủ; hướng dẫn của chúng tôi về git worktree cho các AI coding agent trình bày rất chi tiết cách tạo và tạo nhánh. Chỗ đau nằm ở vòng đời sau chữ “xong”, và nó trở nặng rất nhanh khi thứ tạo ra worktree là một agent có thể mở năm cái trong một phút mà chẳng có chút bản năng dọn dẹp nào. Bài viết này nói về nửa sau đó: kỷ luật dọn dẹp, các câu lệnh cụ thể, những lỗi rình rập ở từng bước, và điểm mà một script tự viết không còn đủ dùng.
Sharkly là một lời giải cho bài toán “ai dọn dẹp”: nó chạy mỗi Task trong worktree riêng và coi worktree đó là một phần trong vòng đời của Task, chứ không phải một thư mục bạn phải nhớ tới. Chúng ta sẽ đến phần đó. Trước tiên là cơ chế, vì bạn nên hiểu cách làm thủ công trước khi quyết định không tự làm bằng tay nữa.

TL;DR
Git worktree là thư mục làm việc thứ hai gắn với một repository, có nhánh, index và HEAD riêng. Agent khiến chúng chồng chất lên nhau vì mỗi lần chạy đều muốn được tách biệt, mà không lần nào tự dọn dẹp. Quy trình dọn dẹp gồm bốn câu lệnh: git worktree list để xem cái gì đang tồn tại, git worktree remove để xóa một worktree đã xong, git worktree prune để dọn metadata cũ, và git worktree lock để bảo vệ cái bạn muốn giữ. Mỗi lệnh đều có một kiểu lỗi riêng, có thể để lại thư mục mồ côi, mất công việc, hoặc nhánh bị kẹt nếu bạn bỏ qua một bước. Cách làm thủ công chỉ ổn với vài worktree. Vượt qua mức đó, hãy gắn mỗi worktree với một bản ghi task để việc dọn dẹp có người chịu trách nhiệm — Sharkly làm điều này tự động.
Vì sao worktree tích tụ nhanh hơn khi có agent
Worktree có một vòng đời mà con người thường quản lý một cách tự nhiên: tạo, làm việc, merge, xóa. Bước xóa phụ thuộc vào việc con người có nhớ hay không. Agent phá vỡ giả định đó theo hai hướng cùng lúc.
Thứ nhất, số lượng. Một lập trình viên chạy bốn agent song song là mỗi giờ tạo ra bốn worktree, chứ không phải mỗi ngày một cái. Bài viết của chúng tôi về chạy nhiều Claude Code agent song song giải thích vì sao con số đó leo nhanh đến vậy. Thứ hai, không có bản năng dọn dẹp. Agent đọc task, làm việc, ghi kết quả rồi dừng. Nó không nghĩ “nhánh đã merge rồi, thư mục này giờ chỉ là gánh nặng”. Vậy nên các thư mục sống lâu hơn cả vòng đời hữu ích của chúng, và những kẻ sống sót đó mới là vấn đề: checkout cũ trên nhánh đã xóa, thí nghiệm dở dang mà agent bỏ ngang, và những cây node_modules trùng lặp ăn hết dung lượng ở từng cái một.
Cái giá không hề trừu tượng. Mỗi worktree là một bản checkout đầy đủ, cộng thêm mọi thứ agent đã cài vào đó. Mười worktree trên một repo JavaScript cỡ trung bình là mười thư mục node_modules. Ổ đĩa đầy lên, git status chậm đi trên toàn bộ tập hợp, và người tiếp theo chạy git worktree list không thể phân biệt đâu là thư mục đang làm việc thật, đâu là rác.
Quy trình dọn dẹp, từng bước một
Đây là toàn bộ vòng đời gói gọn trong bốn câu lệnh. Chạy đúng thứ tự này thì các kiểu lỗi sẽ không xảy ra.
Xem cái gì đang tồn tại. Hãy bắt đầu mọi đợt dọn dẹp từ đây:
git worktree list
# /repo a1b2c3d [main]
# /repo-auth-refactor 4d5e6f7 [auth-refactor]
# /repo-fix-logging 8g9h0i1 [fix-logging]
Lỗi xảy ra nếu bạn bỏ qua bước này: bạn xóa nhầm thư mục. Hai agent làm trên những nhánh có tên na ná nhau sẽ tạo ra các đường dẫn worktree cũng na ná nhau, và xóa nhầm cái đang hoạt động sẽ khiến bạn mất phần việc chưa commit. Hãy đọc danh sách trước khi động vào bất cứ thứ gì.
Xóa một worktree đã xong. Khi nhánh của worktree đã được merge và bạn đã xác nhận không còn gì chưa commit trong đó:
git worktree remove /repo-fix-logging
Lỗi ở đây: remove sẽ từ chối nếu worktree có thay đổi chưa commit hoặc file chưa được track — đó là mặc định an toàn. Động thái không an toàn là với tay lấy --force cho lỗi biến mất. Dùng force trên một worktree bẩn sẽ xóa mất phần việc thật mà agent đã tạo ra nhưng chưa bao giờ commit. Nếu remove báo lỗi, hãy vào xem thư mục trước; lời phàn nàn đó thường là đúng.
Dọn metadata cũ. Nếu một thư mục worktree bị xóa bằng rm -rf thay vì git worktree remove, git vẫn giữ một bản ghi quản trị về nó. Đó là kiểu mồ côi kinh điển:
git worktree prune
git worktree prune --dry-run # preview first
Lỗi ở đây: bỏ qua prune sẽ để lại những mục ma trong git worktree list và tệ hơn, git có thể từ chối dùng lại một nhánh mà nó tưởng vẫn đang được checkout ở đâu đó. prune dọn sạch sổ sách. Hãy chạy --dry-run trước để xem nó sẽ bỏ cái gì trước khi thực sự bỏ. Tài liệu git worktree nói rõ prune coi cái gì là cũ.
Khóa những cái bạn muốn giữ. Một worktree nằm trên ổ ngoài chậm chạp, hay một cái đang chứa thí nghiệm chạy dài, không nên bị một script dọn dẹp hung hăng xóa mất:
git worktree lock /repo-experiment --reason "release repro, keep until 2.0 ships"
Lỗi ở đây: không có lock, một job dọn dẹp chạy mỗi đêm, prune mọi thứ bị coi là “cũ”, có thể xóa mất worktree mà bạn cố ý để dành. Lock kèm một chuỗi lý do chính là khác biệt giữa một script dọn dẹp bạn tin tưởng và một script bạn phải tắt đi sau khi nó nuốt mất thứ gì đó quan trọng.
Khi script dọn dẹp không còn đủ dùng
Bạn có thể tự động hóa cả bốn bước. Một cron job liệt kê worktree, đối chiếu từng nhánh với lịch sử merge, rồi xóa những cái đã merge chỉ gói gọn trong ba mươi dòng shell. Nó chạy được, và với một lập trình viên độc lập chạy vài agent thì thế là đủ. Hãy dùng script khi số lượng worktree còn ít và chỉ một người quản lý repository.
Nó hết đủ dùng ở khả năng phán đoán, chứ không phải ở thông lượng. Script có thể biết một nhánh đã merge. Nó không thể biết một worktree đang chứa phần việc chưa commit của agent mà bạn chưa review, hay một nhánh “cũ” thực ra là một task đang tạm dừng mà ai đó định quay lại làm tiếp. Khoảnh khắc việc dọn dẹp đòi hỏi phải hiểu ý đồ của một worktree, một quy tắc chỉ nhìn vào trạng thái git rồi cũng sẽ có ngày xóa mất thứ quan trọng. Giới hạn còn lại là phối hợp: trên một máy dùng chung, script dọn dẹp của người này không biết agent của người kia đang làm gì, và câu hỏi “xóa cái này có an toàn không” không còn trả lời được chỉ từ git worktree list. Muốn tìm hiểu thêm về vấn đề máy dùng chung đó, hãy xem bài tổng hợp của chúng tôi về các công cụ quản lý nhiều AI coding agent chạy song song.
Một task board thêm được gì
Cách khắc phục là gán cho mỗi worktree một chủ sở hữu tồn tại lâu hơn phiên shell. Gắn mỗi worktree với một bản ghi task, và việc dọn dẹp không còn là “thư mục nào trông có vẻ cũ” mà trở thành “task nào đã xong và đã được review”.
Đây là tầng mà Sharkly ngồi vào. Bạn đã có coding agent; Sharkly biến chúng thành một đội bằng cách biến mỗi lần chạy thành một Task. Khi một Task khởi động, service cục bộ trên Computer đã kết nối sẽ chuẩn bị một worktree tách biệt cho nó. Khi kết quả của Task được trả về để review và có người chấp nhận, vòng đời của worktree kết thúc cùng Task, thay vì nán lại như một thư mục không ai nhớ tới. Câu hỏi dọn dẹp có câu trả lời vì worktree chưa bao giờ là kẻ vô danh.
Sự phân công vẫn rõ ràng. Agent nhận task, làm việc trong các worktree tách biệt, chạy test và trả về diff. Con người định hướng và quyết định bước merge và release. Sharkly không thay thế Claude Code, Codex hay các câu lệnh git ở trên; nó bổ sung bản ghi chung để việc tách biệt, tiến độ, kết quả và dọn dẹp luôn hiển thị từ lúc yêu cầu đến lúc release, thay vì phân tán khắp các terminal. Nếu bạn chỉ chạy một agent và dọn dẹp thủ công mất mười giây, bạn chưa cần thứ này. Khi danh sách worktree dài đến mức trôi khỏi màn hình thì bài toán quản lý mới chính là vấn đề thật, và ghi chú của chúng tôi về giữ con người trong vòng lặp xuyên suốt các lần chạy agent sẽ nói về khía cạnh review của nó.
Danh sách kiểm tra bạn có thể chạy ngay hôm nay
Hãy chạy đợt dọn dẹp này trên bất kỳ repo nào từng có agent làm việc:
git worktree listvà đọc hết trước khi xóa bất cứ thứ gì.- Với mỗi worktree đã xong: xác nhận nhánh đã merge, kiểm tra thư mục sạch, rồi
git worktree remove(tuyệt đối không dùng--forcetrên một cây bẩn). git worktree prune --dry-run, xem xét, rồigit worktree pruneđể dọn metadata mồ côi.git worktree lockmọi worktree bạn cố ý giữ lại, kèm một chuỗi lý do.- Kiểm tra dung lượng:
du -shtrên toàn bộ tập worktree, và xóa các bản cài dependency trùng lặp trong những cây đã chết. - Nếu bạn phải làm việc này hơn một lần mỗi ngày, hãy ngừng viết script dọn dẹp và thay vào đó gán cho mỗi worktree một Task làm chủ sở hữu.
Bạn có thể giữ bốn câu lệnh và chạy thủ công, hoặc chạy các coding agent hiện có của bạn qua Sharkly để worktree được tạo, theo dõi và kết thúc cùng Task mà nó thuộc về.



