Làm cách nào để buộc git sử dụng LF thay vì CR + LF dưới cửa sổ?


335

Tôi muốn buộc git kiểm tra các tệp trong Windows bằng cách LFkhông sử dụng CR+LF. Tôi đã kiểm tra hai tùy chọn cấu hình nhưng tôi không thể tìm thấy sự kết hợp đúng của các cài đặt.

Tôi muốn nó chuyển đổi tất cả các tập tin sang LFvà giữ LFcác tập tin.

Ghi chú: Tôi đã sử dụng autocrlf = inputnhưng điều này chỉ sửa chữa các tệp khi bạn cam kết chúng. Tôi muốn buộc nó sử dụng chúng LF.

Có lẽ tôi đã không rõ ràng: kho lưu trữ đã sử dụng LFnhưng các tệp được kiểm tra bằng msysgit đang sử dụng CR+LFvà tôi muốn buộc msysgit lấy chúng bằng LF: buộc các kết thúc dòng Unix .

>git config --list | grep crlf
core.autocrlf=input

2
autocrlf=inputlà lựa chọn chính xác. Tất nhiên, nó không bảo vệ bạn khỏi các tệp thực sự có cr+lftrong kho lưu trữ hoặc tạo tệp với cr+lftrong một công cụ khác trước khi thêm chúng vào git. Những vấn đề bạn gặp phải mà điều này không làm việc?
CB Bailey

2
Các tệp trong kho lưu trữ đã chỉ sử dụng LFnhưng khi tôi nhận được chúng trong Windows msysgit sẽ chuyển đổi chúng thành CR+LF.
sorin

Phải có một cái gì đó với cấu hình của bạn; Tôi vừa mới thử nghiệm điều này trên bản cài đặt msysgit của tôi. Với autocrlfthiết lập input, git sẽ để lại các nguồn cấp dữ liệu lfmột mình. Bạn có thể gửi đầu ra của git config?
CB Bailey

1
Trong trường hợp đó, tôi khuyên bạn nên đăng nhập một lỗi; tốt nhất là chỉ vào kho lưu trữ kiểm tra thể hiện vấn đề của bạn và bao gồm các bước để tạo lại vì hành vi bạn đang thấy chắc chắn là sai (nhưng tôi không thể tái tạo nó).
CB Bailey

1
Một mẹo nhỏ là cũng đảm bảo rằng bạn đang chạy các lệnh git trên 'git' mà bạn nghĩ là bạn. Ví dụ: bạn có thể đã cài đặt git trên windows và git được cài đặt trên cygwin, vì vậy hãy đảm bảo bạn đã đặt đúng git config.
vào

Câu trả lời:


106

OP đã thêm vào câu hỏi của mình:

các tệp được kiểm tra bằng msysgit đang sử dụng CR+LFvà tôi muốn buộc msysgit lấy chúng vớiLF

Bước đơn giản đầu tiên vẫn sẽ nằm trong một .gitattributestệp:

# 2010
*.txt -crlf

# 2020
*.txt text eol=lf 

(như đã lưu ý trong các nhận xét của cháu , đề cập đến .gitattributeschuyển đổi Cuối dòng ), để tránh mọi CRLFchuyển đổi cho các tệp có chính xác eol.

tôi luôn khuyến nghị git config --global core.autocrlf false tắt mọi chuyển đổi (sẽ áp dụng cho tất cả các tệp được phiên bản)

Xem thực tiễn tốt nhất cho cấu hình git đa nền tảng?

Kể từ Git 2.16 (Q1 2018), bạn có thể sử dụng git add --renormalize .để áp dụng các .gitattributescài đặt đó ngay lập tức.


Nhưng bước mạnh mẽ thứ hai liên quan đến trình điều khiển bộ lọc gitattribution và thêm bước smudge

trình điều khiển bộ lọc

Bất cứ khi nào bạn sẽ cập nhật cây làm việc của mình, một tập lệnh có thể, chỉ cho các tệp bạn đã chỉ định trong .gitattributes, buộc LF eolvà bất kỳ tùy chọn định dạng nào khác mà bạn muốn thực thi.
Nếu cleartập lệnh "" không làm gì cả, bạn sẽ (sau khi cam kết) chuyển đổi các tệp của mình, áp dụng chính xác định dạng bạn cần chúng tuân theo.


Một câu hỏi: * .txt đề cập đến tất cả các tệp có phần mở rộng .txt hoặc cho tất cả các tệp văn bản (không phải nhị phân)? Tôi không thể tạo một danh sách với tất cả các loại phần mở rộng tập tin tôi sẽ có trong dự án.
sorin

1
@Sorin: tất cả các tệp có .txtphần mở rộng. Trước tiên, tốt nhất là thiết lập điều này và kiểm tra nó trên một nhóm cụ thể, trước khi khái quát hóa thành * và thêm quy tắc phủ định !*.xyz ...để loại trừ một số tệp khỏi quy tắc đó.
VonC

1
Đến bây giờ, các .gitattributesdòng nên đọc: *.txt text eol=lftheo git-scm.com/docs/gitattribut
cháu

@grandchild Cảm ơn bạn. Tôi đã bao gồm nhận xét của bạn trong câu trả lời để dễ nhìn hơn.
VonC

Tôi đoán sau khi chúng tôi thêm .gitattributeschúng tôi phải làmgit add --renormalize .
shuva

460

Cách thích hợp để có được các kết thúc LF trong Windows là trước tiên được đặt core.autocrlfthành false:

git config --global core.autocrlf false

Bạn cần phải làm điều này nếu bạn đang sử dụng msysgit, bởi vì nó đặt nó truetrong cài đặt hệ thống của nó.

Bây giờ git sẽ không làm bất kỳ dòng kết thúc bình thường hóa. Nếu bạn muốn các tệp bạn đăng ký được chuẩn hóa, hãy làm điều này: Đặt text=autotrong .gitattributestất cả các tệp:

* text=auto

Và đặt core.eolthành lf:

git config --global core.eol lf

Bây giờ bạn cũng có thể chuyển các repos đơn sang crlf (trong thư mục làm việc!) Bằng cách chạy

git config core.eol crlf

Sau khi bạn thực hiện cấu hình, bạn có thể muốn git bình thường hóa tất cả các tệp trong repo . Để làm điều này, hãy đi đến thư mục gốc của repo của bạn và chạy các lệnh sau:

git rm --cached -rf .
git diff --cached --name-only -z | xargs -n 50 -0 git add -f

Nếu bây giờ bạn muốn git cũng bình thường hóa các tệp trong thư mục làm việc của bạn , hãy chạy các lệnh sau:

git ls-files -z | xargs -0 rm
git checkout .

3
Tôi đang nhận được đường dẫn gây tử vong '' không khớp với bất kỳ tệp nào, ngay sau đógit diff --cached --name-only -z | xargs -0 git add
CMCDragonkai

3
đầu ra là git diff --cached --name-onlygì?
Biên niên sử

1
Điều đáng nói là bạn có thể đặt cấu hình này trong khi nhân bản repo trong câu hỏi, ví dụ git clone --config core.autocrlf=false <repo path>.
Chris Long

240

Tôi trở lại câu trả lời này khá thường xuyên, mặc dù không có câu nào trong số này hoàn toàn phù hợp với tôi. Điều đó nói rằng, câu trả lời đúng cho tôi là một hỗn hợp của những người khác.

Những gì tôi tìm thấy công việc là như sau:

 git config --global core.eol lf
 git config --global core.autocrlf input

Đối với các repos đã được kiểm tra sau khi các cài đặt chung đó được đặt, mọi thứ sẽ được kiểm tra như bất cứ thứ gì trong repo - hy vọng LF( \n). Bất kỳ CRLFsẽ được chuyển đổi thành chỉ LFkhi đăng ký.

Với một repo hiện có mà bạn đã kiểm tra - có kết thúc dòng chính xác trong repo nhưng không phải là bản sao làm việc của bạn - bạn có thể chạy các lệnh sau để sửa nó:

git rm -rf --cached .
git reset --hard HEAD

Điều này sẽ xóa ( rm) đệ quy ( r) mà không có dấu nhắc ( -f), tất cả các tệp ngoại trừ những tệp mà bạn đã chỉnh sửa ( --cached), khỏi thư mục hiện tại ( .). Sau resetđó trả lại tất cả các tệp đó về trạng thái nơi chúng có kết thúc dòng thực sự của chúng (khớp với những gì trong repo).

Nếu bạn cần sửa lỗi kết thúc dòng của các tệp trong một repo, tôi khuyên bạn nên lấy một trình soạn thảo sẽ cho phép bạn làm điều đó với số lượng lớn như IntelliJ hoặc Sublime Text, nhưng tôi chắc chắn bất kỳ ai giỏi đều có thể hỗ trợ điều này.


1
Chúng tôi có một repo duy nhất với các thư mục con yêu cầu xử lý kết thúc dòng khác nhau. Vì vậy, thiết lập một tùy chọn toàn cầu không hoạt động cho việc này. Ngay cả trong repo duy nhất. Làm thế nào để bạn áp dụng các cài đặt tương tự trong .gitattribut?
RobG

Notepad++cũng hiển thị kết thúc dòng của tệp được mở hiện tại ở góc dưới bên phải. Nhấp chuột phải vào trường đó sẽ cho phép bạn thay đổi kết thúc dòng.
winklerrr

1
Các core.autocrlf inputtùy chọn ghi đè các core.eolthiết lập, vì vậy thiết lập cả hai là không cần thiết. (Xem git-scm.com/docs/git-config )
Andrew Marshall

1
Cảm ơn bạn, với sự giúp đỡ của bạn, tôi đã chinh phục được lint và Linux. Và bây giờ có thể kiểm tra trong các tập tin.
GC_

57

Bối cảnh

nếu bạn

  1. muốn buộc tất cả người dùng phải có kết thúc dòng LF cho tệp văn bản và
  2. bạn không thể đảm bảo rằng tất cả người dùng thay đổi cấu hình git của họ,

bạn có thể làm điều đó bắt đầu với git 2.10. 2.10 trở lên là bắt buộc, vì 2.10 đã sửa lỗi hành vi của text = auto cùng với eol = lf . Nguồn .

Giải pháp

Đặt một .gitattributestệp trong thư mục gốc của kho git của bạn có nội dung sau:

* text=auto eol=lf

Cam kết nó.

Tùy chọn chỉnh

Bạn cũng có thể thêm một thư .editorconfigmục gốc trong kho lưu trữ của mình để đảm bảo rằng công cụ hiện đại tạo ra các tệp mới với các kết thúc dòng mong muốn.

# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true

3
Đây là giải pháp tốt nhất cho tôi. Tôi cũng đã kết hợp điều này với Editorconfig.org để khi viết bằng Intellij tôi sẽ viết ra các EOL của LF.
Jazzepi

Đây là giải pháp tốt nhất. Không cần phải tự chạy bất kỳ lệnh cấu hình nào!
Cameron Tacklind

26

core.autocrlf=inputlà cài đặt phù hợp cho những gì bạn muốn, nhưng bạn có thể phải thực hiện một git update-index --refreshvà / hoặc một git reset --hardthay đổi để có hiệu lực.

Khi core.autocrlfđược đặt thành input, git sẽ không áp dụng chuyển đổi dòng mới khi thanh toán (vì vậy nếu bạn có LF trong repo, bạn sẽ nhận được LF), nhưng sẽ đảm bảo rằng trong trường hợp bạn làm hỏng và giới thiệu một số CRLF đang hoạt động sao chép bằng cách nào đó, họ sẽ không tìm đường vào repo.


19
Các lệnh nên là git rm --cached -r. && git reset
--hard

0

Bạn có thể tìm giải pháp cho vấn đề này tại: https://help.github.com/en/github/USE-git/configuring-git-to-handle-line-endings

Mô tả đơn giản về cách bạn có thể giải quyết vấn đề này trên windows:

Cài đặt chung cho kết thúc dòng Lệnh Lệnh git config core.autocrlf được sử dụng để thay đổi cách Git xử lý kết thúc dòng. Nó cần một đối số duy nhất.

Trên Windows, bạn chỉ cần chuyển đúng sang cấu hình. Ví dụ: C:> git config --global core.autocrlf true

Chúc may mắn, tôi hy vọng tôi đã giúp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.