Khắc phục nhanh (TL;DR)
Nếu bạn cần sửa lỗi ngay lập tức, hãy chạy ba lệnh sau bên trong thư mục gốc của kho lưu trữ để đặt lại quyền và buộc Git hoạt động trơn tru với nhóm của bạn:
# 1. Thay đổi quyền sở hữu nhóm thành nhóm của bạn (ví dụ: 'developers')
sudo chown -R :developers .git
# 2. Cấp quyền đọc/ghi/truy cập (traversal) cho nhóm
sudo chmod -R g+rwX .git
# 3. Buộc Git tuân thủ quyền của nhóm cho tất cả các đối tượng trong tương lai
git config core.sharedRepository group
Điều gì thực sự đang xảy ra?
Đây là một xung đột quyền Linux điển hình. Điều này thường xảy ra trên các máy chủ staging hoặc máy trạm dùng chung, nơi có 3 hoặc 4 lập trình viên triển khai mã qua SSH bằng tài khoản cá nhân của họ.
Xung đột bắt đầu với umask mặc định. Khi Alice chạy lệnh git pull, Git tạo các đối tượng mới trong thư mục .git/objects. Theo mặc định, Alice sở hữu các tệp này và chúng thường ở chế độ chỉ đọc đối với những người khác. Khi Bob cố gắng commit một thay đổi năm phút sau đó, Git cố gắng sửa đổi các thư mục đó. Bob gặp lỗi vì không có quyền ghi vào các tệp của Alice.
Các giải pháp lâu dài
1. Sửa chữa quyền sở hữu tệp hiện có
Trước tiên, bạn phải dọn dẹp mớ hỗn độn hiện tại. Bạn cần đảm bảo mọi người dùng trong nhóm chung đều có thể thao tác với cơ sở dữ liệu của kho lưu trữ. Hãy bắt đầu bằng cách xác định tên nhóm dùng chung của bạn.
# Xem bạn thuộc về các nhóm nào
groups
# Cập nhật đệ quy nhóm của thư mục .git
sudo chown -R :developers .git
# Áp dụng 'rwX' để nhóm có thể đọc, ghi và truy cập vào các thư mục
sudo chmod -R g+rwX .git
2. "Viên đạn bạc": Chế độ Git Shared Repository
Việc sửa quyền một lần chỉ là giải pháp tạm thời. Lần tới khi ai đó push mã, Git sẽ lại tạo các tệp mới với quyền hạn chế 0644. Bạn cần làm cho kho lưu trữ ở chế độ "nhận biết chia sẻ" (shared-aware).
git config core.sharedRepository group
Cấu hình này thay đổi hành vi của Git. Thay vì sử dụng mask mặc định của người dùng, nó buộc các tệp mới phải có quyền ghi cho nhóm (thường là 0664 hoặc 0775). Nếu bạn đang ở trên một máy chủ nội bộ hoàn toàn mở, bạn có thể sử dụng world thay vì group, mặc dù đó hiếm khi là lựa chọn an toàn nhất.
3. Kiểm tra lại tư cách thành viên nhóm
Giải pháp sẽ thất bại nếu người dùng của bạn không thực sự nằm trong nhóm bạn vừa chỉ định. Thêm người dùng vào nhóm developers là một lệnh nhanh chóng:
sudo usermod -a -G developers username
Lưu ý: các thay đổi về nhóm không có hiệu lực ngay lập tức. Người dùng phải đăng xuất và đăng nhập lại để hệ thống nhận diện các quyền mới của họ.
Cách xác minh bản sửa lỗi
Đừng chỉ nghe lời tôi. Hãy chuyển sang một tài khoản người dùng khác và thử kích hoạt một bản cập nhật trên toàn bộ kho lưu trữ. Tác vụ dọn rác (garbage collection) là một bài kiểm tra hoàn hảo vì nó tác động đến hầu hết mọi đối tượng.
# Kiểm tra quyền của thư mục objects
ls -la .git/objects
# Chạy dọn rác thủ công
git gc
Nếu git gc hoàn tất mà không báo lỗi "insufficient permission", bạn đã xử lý thành công kho lưu trữ.
Mẹo chuyên gia để phòng ngừa
Quyền trong Linux có thể gây đau đầu, đặc biệt là khi bạn bắt đầu tính toán các giá trị bát phân như 775 hoặc 664. Nếu bạn đang thiết lập một môi trường phức tạp, hãy sử dụng Trình tính toán quyền Unix để hình dung chính xác ai có quyền truy cập. Nó giúp bạn tránh vô tình tạo ra lỗ hổng bảo mật trong khi cố gắng khắc phục điểm nghẽn của quy trình làm việc.
Giải pháp Sticky Bit
Đối với cách tiếp cận "thiết lập một lần và quên đi", hãy sử dụng bit setgid. Điều này đảm bảo rằng bất kỳ tệp mới nào được tạo bên trong .git/objects sẽ tự động kế thừa nhóm developers, bất kể ai là người tạo ra nó:
find .git/objects -type d -exec chmod g+s {} +

