Git Worktree: Quản lý nhiều branch song song trong một repo

Tại sao cần Git Worktree?

Git workflow thông thường ép bạn chuyển branch liên tục: git checkout feature-A, sửa, rồi git checkout main, hotfix, rồi quay lại. Mỗi lần checkout đổi context, stash rườm rà, và branch dở dang không thể chạy song song. Git Worktree giải quyết bằng cách tạo nhiều working directory khác nhau, mỗi nơi checkout một branch riêng, cùng tồn tại trong cùng một repo.

Worktree phù hợp khi bạn cần review PR mà không muốn stash, chạy test trên cũ/mới song song, hoặc deploy nhánh staging trong khi vẫn phát triển feature. Tài liệu chính thức Git gọi đây là “checkout nhiều branch cùng lúc”.

Vấn đề cốt lõi của quy trình Git truyền thống là mô hình working directory đơn. Khi bạn đang làm việc trên branch feature-auth và bỗng nhiên cần sửa một bug khẩn trên main, bạn buộc phải: (1) git stash hoặc commit tạm thay đổi chưa xong, (2) git checkout main, (3) sửa bug, (4) git checkout feature-auth, (5) git stash pop hoặc tiếp tục commit. Quy trình này không chỉ tốn thời gian mà còn mang lại rủi ro: conflict khi pop stash, quên commit thay đổi, hoặc vô tình push nhầm branch.

Git Worktree (được giới thiệu từ Git 2.5 năm 2015) xóa bỏ giới hạn này bằng cách cho phép một repository có nhiều working directory liên kết. Mỗi worktree có HEAD, index, và working tree riêng, nhưng cùng chia sẻ một .git directory (object database, refs, config). Điều này có nghĩa là: history, branches, tags, remote tracking đều dùng chung — không mất dung lượng ổ cứng và không cần sync thủ công.

Hai terminal song song hiển thị git worktree trong cùng repository
Hai worktree song song trong cùng repo

Cú pháp cơ bản

Thêm worktree mới:

git worktree add ../project-feature-A feature-A

Lệnh này tạo thư mục ../project-feature-A, checkout branch feature-A vào đó. Bạn có thể cd ../project-feature-A và làm việc bình thường: sửa file, chạy test, commit. Về repo gốc, branch feature-A vẫn checkout sẵn, không bị ảnh hưởng.

Nếu branch chưa tồn tại, Git sẽ tự tạo mới:

git worktree add ../hotfix-bug-42 -b hotfix-bug-42 main

Tạo branch hotfix-bug-42 từ main và checkout vào worktree mới.

Liệt kê worktree hiện có:

git worktree list

Output ví dụ:

/path/to/repo               abc1234 [main]
/path/to/repo-feature-A       def5678 [feature-A]
/path/to/hotfix-bug-42        fedcba9 [hotfix-bug-42]

Mỗi dòng hiển thị: đường dẫn worktree, commit hash hiện tại (HEAD), và tên branch đang checkout.

Xóa worktree khi không cần:

git worktree remove ../project-feature-A

Nếu có thay đổi chưa commit, dùng git worktree remove --force. Lưu ý: xóa worktree không xóa branch — branch vẫn còn trong .git/refs/heads/.

Quy tắc tránh xung đột

  • Không checkout cùng một branch vào hai worktree khác nhau — Git chặn lỗi này ngay.
  • Không force-push từ worktree nếu bạn quên đang ở branch nào. Dùng git branch --show-current trước khi push.
  • Không chạy cùng một process server (npm start, python app.py) từ hai worktree khác nếu chúng dùng port giống nhau.
Terminal hiển thị lệnh git branch --show-current và kiểm tra branch trước khi push
Kiểm tra branch hiện tại trước khi push

Worktree thao tác trực tiếp trên .git, không phải clone mới. Vì vậy disk space tiết kiệm, và mọi thay đổi đều là thao tác Git thật — push, pull, rebase bình thường.

Một điểm quan trọng: .gitignore.git/config là shared giữa tất cả worktree. Nếu bạn cần config khác cho từng worktree (ví dụ user.email riêng cho worktree công việc vs cá nhân), hãy dùng git config --local bên trong thư mục worktree đó.

Kịch bản thực tế

Review PR: bạn đang code trên feature-login, cần kiểm tra PR #42 trên feature-api. Thay vì stash và checkout, bạn git worktree add ../pr-42 feature-api, review xong git worktree remove ../pr-42, quay lại feature-login không mất context.

Đây là kịch bản phổ biến nhất trong team development. Khi review PR, bạn thường cần: chạy test suite, kiểm tra thay đổi UI, hoặc debug một bug được báo cáo trong PR. Với worktree, bạn có thể mở thư mục ../pr-42 trong IDE riêng, chạy server development trên port khác, và test end-to-end mà không ảnh hưởng đến môi trường đang phát triển feature của mình.

Hotfix trên cũ: production đang chạy v1.2, bạn đang code v2.0. Cần fix bug trên v1.2. git worktree add ../hotfix-v1.2 v1.2, sửa, tag, push. Worktree v2.0 không bị ảnh hưởng.

Kịch bản này đặc biệt quan trọng cho các sản phẩm có vòng đời release dài (LTS). Khi phát triển version mới lớn (v2.0 có breaking changes), team vẫn phải maintain version cũ (v1.2) để fix security patch. Với worktree, bạn có thể maintain cả hai song song mà không cần clone riêng hay stash liên tục.

So sánh hai phiên bản: muốn chạy v1.0v2.0 song song để xem khác biệt UI. Hai worktree, hai terminal, hai port.

Trong quá trình refactor hoặc migration, việc so sánh hành vi của hệ thống cũ và mới là rất quan trọng. Worktree cho phép bạn khởi chạy cả hai phiên bản đồng thời: một terminal chạy npm run dev trên worktree v1.0 ở port 3000, terminal khác chạy npm run dev trên worktree v2.0 ở port 3001. Bạn có thể mở hai tab trình duyệt cạnh nhau và so sánh trực quan.

Parallel CI/CD testing: Chạy test suite trên nhiều branch cùng lúc mà không cần multiple runners.

Nếu CI server của bạn có tài nguyên đủ (RAM, CPU), bạn có thể cấu hình pipeline tạo ra multiple worktree và chạy test song song trên các branch khác nhau. Điều này giảm đáng kể thời gian feedback cho monorepo lớn nơi test suite có thể mất 15-30 phút mỗi lần chạy.

Giới hạn

Worktree không giải quyết merge conflict thay bạn. Nếu hai worktree cùng sửa cùng file, conflict vẫn xảy ra khi merge. Tool CI/CD cũng cần cấu hình lại nếu nó giả định một working directory. Với repo lớn có nhiều submodule, worktree mới cần sync submodule riêng.

Các hạn chế kỹ thuật cần lưu ý:

  1. Submodule: Khi tạo worktree mới, submodule không tự động checkout. Bạn cần chạy git submodule update --init bên trong worktree mới.
  2. Linked worktree và bare repo: Nếu repo gốc là bare (không có working tree), tất cả worktree đều là linked worktree — không có “main worktree” đặc biệt.
  3. Filesystem limitations: Trên một số filesystem mạng (NFS, SMB), lock files của Git có thể không hoạt động đúng, dẫn đến corruption. Nên dùng local filesystem.
  4. IDE integration: Một số IDE (VS Code, IntelliJ) chưa hỗ trợ native multi-worktree. Bạn thường phải mở từng worktree như một project riêng biệt.

Ngoài ra, worktree không phù hợp cho các tình huống: (1) cần isolation hoàn toàn (ví dụ: test dependency version conflict) — lúc này container/VM tốt hơn; (2) làm việc offline kéo dài — worktree vẫn phụ thuộc vào .git chung nên cần kết nối nếu remote thay đổi.

Best practices

  • Đặt tên thư mục worktree theo pattern: ../- để dễ nhận diện.
  • Dùng git worktree prune định kỳ để dọn dẹp administrative files của worktree đã bị xóa thủ công (rm -rf thư mục mà không dùng git worktree remove).
  • Cấu hình gc.worktreePruneExpire (mặc định 3 tháng) nếu bạn thường tạo worktree tạm thời.
  • Khi làm việc trên worktree, luôn chạy git branch --show-current trước các lệnh nguy hiểm như push --force, reset --hard.

Nguồn tham khảo: Git Worktree Documentation, Atlassian Git Worktree Tutorial

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

Homebrew Package Manager quản lý công cụ trên macOS

Homebrew là gì? Homebrew là package manager mã nguồn mở cho macOS và Linux. Nó giúp lập trình viên cài, cập nhật, gỡ cài đặt công cụ dòng lệnh (CLI)…

Xem thêm

TypeScript satisfies operator là gì? Kiểm tra kiểu không đổi biến

TypeScript satisfies operator (toán tử satisfies) cho phép kiểm tra kiểu của một biểu thức phù hợp với kiểu mong đợi mà không thay đổi kiểu suy luận gốc của…

Xem thêm

Terraform là gì? Infrastructure as Code cho cloud đa nền tảng

Terraform là gì? Infrastructure as Code cho cloud đa nền tảng Terraform là công cụ Infrastructure as Code (IaC) mã nguồn mở được phát triển bởi HashiCorp. Nó cho phép…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất