Nguyên nhân có thể # 1 - Chuẩn hóa kết thúc dòng
Một tình huống có thể xảy ra là khi tệp được đề cập đã được kiểm tra vào kho lưu trữ mà không có cấu hình chính xác cho các kết thúc dòng (1) dẫn đến một tệp trong kho lưu trữ có đầu cuối dòng không chính xác hoặc kết thúc dòng hỗn hợp. Để xác nhận, xác minh rằng git diff
chỉ hiển thị các thay đổi trong kết thúc dòng (theo mặc định có thể không hiển thị các thay đổi này, hãy thử git diff | cat -v
xem trả về vận chuyển dưới dạng ^M
ký tự bằng chữ ).
Sau đó, ai đó có thể đã thêm .gitattributes
hoặc sửa đổi core.autocrlf
cài đặt để bình thường hóa kết thúc dòng (2). Dựa trên .gitattributes
cấu hình toàn cầu hoặc toàn cầu, Git đã áp dụng các thay đổi cục bộ cho bản sao làm việc của bạn áp dụng chuẩn hóa kết thúc dòng được yêu cầu. Thật không may, vì một số lý do git reset --hard
không hoàn tác những thay đổi chuẩn hóa dòng này.
Giải pháp
Cách giải quyết trong đó các kết thúc dòng cục bộ được đặt lại sẽ không giải quyết được vấn đề. Mỗi khi tập tin được "nhìn thấy" bởi git, nó sẽ thử và áp dụng lại chuẩn hóa, dẫn đến cùng một vấn đề.
Tùy chọn tốt nhất là để git áp dụng chuẩn hóa mà nó muốn bằng cách chuẩn hóa tất cả các kết thúc dòng trong repo để khớp với .gitattributes
và thực hiện các thay đổi đó - xem Cố gắng sửa các kết thúc dòng bằng nhánh lọc git, nhưng không gặp may .
Nếu bạn thực sự muốn thử và hoàn nguyên các thay đổi cho tệp theo cách thủ công thì giải pháp đơn giản nhất dường như là xóa các tệp đã sửa đổi, và sau đó nói với git để khôi phục chúng, mặc dù tôi lưu ý rằng giải pháp này dường như không hoạt động ổn định 100% thời gian ( CẢNH BÁO: KHÔNG chạy cái này nếu các tệp đã sửa đổi của bạn có các thay đổi khác với kết thúc dòng !!):
git status --porcelain | grep "^ M" | cut -c4- | xargs rm
git checkout -- .
Lưu ý rằng, trừ khi bạn bình thường hóa các kết thúc dòng trong kho lưu trữ tại một số điểm, bạn sẽ tiếp tục gặp phải vấn đề này.
Nguyên nhân có thể # 2 - Trường hợp không nhạy cảm
Nguyên nhân thứ hai có thể là sự không nhạy cảm trường hợp trên Windows hoặc Mac OS / X. Ví dụ: giả sử một đường dẫn như sau tồn tại trong kho lưu trữ:
/foo/bar
Bây giờ ai đó trên Linux cam kết các tệp vào /foo/Bar
(có thể là do công cụ xây dựng hoặc thứ gì đó đã tạo thư mục đó) và đẩy. Trên Linux, đây thực sự là hai thư mục riêng biệt:
/foo/bar/fileA
/foo/Bar/fileA
Kiểm tra repo này ra trên Windows hoặc Mac có thể dẫn đến biến đổi fileA
mà không thể được đặt lại, vì trên mỗi thiết lập lại, git trên Windows để kiểm tra /foo/bar/fileA
, và sau đó vì Windows là trường hợp nhạy cảm, ghi đè nội dung của fileA
với/foo/Bar/fileA
, kết quả là họ bị "biến dạng".
Một trường hợp khác có thể là (các) tệp riêng lẻ tồn tại trong repo, khi được kiểm tra trên một hệ thống tệp không nhạy cảm trường hợp, sẽ chồng lấp. Ví dụ:
/foo/bar/fileA
/foo/bar/filea
Có thể có những tình huống tương tự khác có thể gây ra vấn đề như vậy.
git về trường hợp hệ thống tập tin không nhạy cảm thực sự sẽ phát hiện tình huống này và hiển thị một thông báo cảnh báo hữu ích, nhưng hiện tại thì không (điều này có thể thay đổi trong tương lai - xem cuộc thảo luận này và các bản vá được đề xuất có liên quan trên danh sách gửi thư của git.git).
Giải pháp
Giải pháp là đưa trường hợp của các tệp trong chỉ mục git và trường hợp trên hệ thống tệp Windows vào căn chỉnh. Điều này có thể được thực hiện trên Linux, nó sẽ hiển thị trạng thái thực sự của mọi thứ, HOẶC trên Windows với tiện ích nguồn mở rất hữu ích Git-Unite . Git-Unite sẽ áp dụng các thay đổi trường hợp cần thiết cho chỉ số git, sau đó có thể được cam kết với repo.
(1) Đây là khả năng nhất bởi người sử dụng Windows, mà không cần bất kỳ .gitattributes
định nghĩa cho các tập tin trong câu hỏi, và sử dụng các thiết lập mặc định toàn cầu cho core.autocrlf
đó làfalse
(xem (2)).
(2) http://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line/
.
là viết tắt của thư mục hiện tại không phải thư mục gốc