Kích hoạt Git FSMonitor và Untracked Cache: Tăng tốc git status trên Repo cực lớn

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

1. Vấn đề: Khi git status làm nghẽn nhịp làm việc

Làm việc với monorepo hay các dự án hàng trăm nghìn file, độ trễ terminal luôn là nỗi phiền toái lớn. Bạn gõ git status rồi phải đợi 5 đến 10 giây mới thấy kết quả. Lệnh này lặp lại hàng chục lần mỗi ngày. Cảm giác chờ đợi liên tục ngắt quãng dòng suy nghĩ và làm giảm năng suất đáng kể.

Trước đây, mình từng gặp tình trạng này trên một repository hơn 320.000 file (chủ yếu là code base PHP/Node.js lâu năm kết hợp submodule). Mỗi lần kiểm tra branch hay commit, Git mất hơn 8 giây chỉ để quét trạng thái. Từ phiên bản Git 2.37+, hai tính năng có sẵn gồm Untracked Cache và FSMonitor (File System Monitor) đã giải quyết triệt để bài toán này. Sau khi bật, thời gian thực thi lệnh giảm từ 8.24 giây xuống còn 0.14 giây.

2. Tại sao Git mặc định lại quét chậm?

Để tối ưu hiệu quả, trước hết cần nhìn vào cách Git kiểm tra thay đổi file trên ổ cứng.

Cơ chế quét mặc định qua lstat()

Mỗi khi bạn chạy git status, Git phải so sánh working tree với index. Hệ thống duyệt đệ quy toàn bộ thư mục và gọi system call lstat() trên từng file một. Với dự án 300.000 file, ổ cứng phải xử lý ngần ấy lượt I/O disk. Tốc độ phản hồi vì thế phụ thuộc hoàn toàn vào băng thông đọc của ổ đĩa.

Untracked Cache (core.untrackedCache)

Tính năng này lưu lại mtime (thời gian sửa đổi gần nhất) của từng thư mục. Khi kiểm tra untracked file, nếu mtime của thư mục cha không đổi, Git lập tức bỏ qua toàn bộ cây con bên trong. Nhờ vậy, Git không tốn tài nguyên đọc sâu vào những thư mục tĩnh khổng lồ như node_modules hay vendor.

FSMonitor (core.fsmonitor)

FSMonitor thay đổi hoàn toàn cách tiếp cận. Thay vì để Git tự đi quét từng ngóc ngách, một tiến trình daemon nền sẽ lắng nghe sự kiện từ hệ điều hành (FSEvents trên macOS, ReadDirectoryChangesW trên Windows, inotify trên Linux). Khi bạn gõ git status, Git chỉ cần hỏi daemon: “Từ lần kiểm tra trước đến giờ, những file nào vừa thay đổi?” Daemon trả về danh sách vài file cụ thể trong tích tắc. Git chỉ cần đọc đúng những file đó thay vì duyệt cả repo.

3. Các bước kích hoạt và đo lường

Bước 1: Kiểm tra phiên bản Git và tính tương thích

Đầu tiên, kiểm tra phiên bản Git trên máy. Bạn cần Git từ 2.37.0 trở lên để dùng FSMonitor tích hợp sẵn mà không phải cài thêm Watchman ngoài:

git --version

Tiếp theo, kiểm tra xem filesystem của phân vùng ổ cứng có hỗ trợ mtime chính xác cho Untracked Cache hay không:

git update-index --test-untracked-cache

Nếu dòng cuối cùng trả về OK, hệ thống của bạn đã sẵn sàng.

Bước 2: Bật Untracked Cache

Chạy hai lệnh sau trong thư mục dự án:

# Bật cấu hình ghi cache file untracked
git config core.untrackedCache true

# Khởi tạo dữ liệu cache ban đầu vào index
git update-index --untracked-cache

Bước 3: Kích hoạt Built-in FSMonitor

Bật tiến trình giám sát file tích hợp:

# Bật riêng cho repository hiện tại
git config core.fsmonitor true

# Hoặc áp dụng toàn cục cho mọi repo trên máy
git config --global core.fsmonitor true

Ở lần gọi lệnh Git kế tiếp, daemon nền git-fsmonitor--daemon sẽ tự khởi động và duy trì theo dõi trong suốt phiên làm việc.

Bước 4: Đo lường hiệu năng thực tế (Benchmark)

Sử dụng biến môi trường GIT_TRACE2_PERF để in chi tiết thời gian thực thi:

GIT_TRACE2_PERF=1 git status

Số liệu đo đạc thực tế trên repo 320.000 files (ổ SSD NVMe PCIe 4.0):

  • Chưa bật tối ưu: data: ... status: 8.241320 s (quét tuần tự toàn bộ disk)
  • Chỉ bật Untracked Cache: data: ... status: 3.110540 s (tiết kiệm hơn 62% thời gian)
  • Bật đồng thời cả hai: data: ... status: 0.142010 s (phản hồi gần như ngay lập tức)

Kinh nghiệm thực tế cần lưu ý

  • Ổ đĩa mạng (NFS/SMB): FSMonitor không nhận được filesystem events qua network share. Chỉ nên áp dụng cho ổ đĩa gắn trực tiếp (local SSD/NVMe).
  • WSL2 trên Windows: Nếu code nằm ở ổ Windows (đường dẫn /mnt/c/...), FSMonitor sẽ nghẽn do lớp chuyển tiếp 9P. Bạn nên đưa toàn bộ source code vào filesystem Linux gốc (ví dụ /home/username/code) để đạt tốc độ tối đa.
  • Xử lý khi cần tắt: Nếu gặp hiện tượng sai lệch cache trong các tình huống hy hữu, tắt nhanh bằng lệnh: git config core.fsmonitor false.

4. Tổng kết

Hai thiết lập core.untrackedCache và core.fsmonitor đưa tốc độ phản hồi của Git về mức mili-giây mà không yêu cầu cài đặt thêm công cụ phức tạp. Với các dự án quy mô từ vài chục nghìn file trở lên, đây là cấu hình nên được bật mặc định ngay từ đầu.

Share: