Tại sao tôi nên sử dụng core.autocrlf = true trong Git?


296

Tôi có kho lưu trữ Git được truy cập từ cả Windows và OS X và tôi biết rằng đã chứa một số tệp có kết thúc dòng CRLF. Theo như tôi có thể nói, có hai cách để giải quyết vấn đề này:

  1. Đặt core.autocrlfđể falseở khắp mọi nơi,

  2. Làm theo các hướng dẫn ở đây (được lặp lại trên các trang trợ giúp của GitHub) để chuyển đổi kho lưu trữ để chỉ chứa các kết thúc dòng của LF và sau đó được đặt core.autocrlfthành truetrên Windows và inputtrên OS X. Vấn đề với việc này là nếu tôi có bất kỳ tệp nhị phân nào trong kho lưu trữ cái đó:

    1. không được đánh dấu chính xác là nhị phân trong gitattribut và
    2. tình cờ có chứa cả CRLF và LF,

    họ sẽ bị hỏng Có thể kho lưu trữ của tôi chứa các tập tin như vậy.

Vậy tại sao tôi không nên tắt chuyển đổi kết thúc dòng của Git? Có rất nhiều cảnh báo mơ hồ trên web về việc core.autocrlfđã tắt gây ra sự cố, nhưng rất ít vấn đề cụ thể ; điều duy nhất tôi tìm thấy cho đến nay là kdiff3 không thể xử lý các kết thúc CRLF (không phải là vấn đề đối với tôi) và một số trình soạn thảo văn bản có vấn đề kết thúc dòng (cũng không phải là vấn đề đối với tôi).

Kho lưu trữ là nội bộ của công ty tôi và vì vậy tôi không cần phải lo lắng về việc chia sẻ nó với những người có cài đặt autocrlf khác nhau hoặc yêu cầu kết thúc dòng.

Có bất kỳ vấn đề nào khác khi chỉ để lại kết thúc dòng như là tôi không biết?


1
Sẽ stackoverflow.com/questions/2333424/... giúp đỡ? Tôi có liên kết đến các lý do cụ thể để rời khỏi autocrlfsai.
VonC

3
@VonC Cảm ơn, nhưng tôi đã có thể ra lệnh rằng tất cả người dùng trong công ty đặt <code> autocrlf </ code> thành false và hiện tin rằng đó là lựa chọn tốt nhất. Nhưng tôi muốn biết liệu có bất kỳ lý do nào khiến tôi không nên làm điều đó không, bởi vì tôi có thể tìm thấy có rất nhiều người (ví dụ như GitHub) nói rằng tôi nên đặt autocrlf nhưng không có thông tin cụ thể thực tế về lý do.
Giàu

3
@VonC tức là tôi không tìm lý do để đặt autocrlfthành false. Tôi đang tìm kiếm lý do để đặt nó thành sự thật.
Giàu

9
Tại sao không sử dụng autocrlf = input: nó dường như là độ phân giải hoàn hảo giữa hai thái cực: bạn giữ repo sạch khỏi cRLF và các nhà phát triển Windows cục bộ có thể sử dụng bất cứ thứ gì họ muốn mà không cần các tệp cục bộ tự động thực hiện. ( trueTheo ý kiến ​​của tôi, họ có thể muốn LF vì nhiều lý do, vì vậy, thật tệ, theo quan điểm của tôi.) Tôi không thể thấy bất kỳ nhược điểm nào khi sử dụng autocrlf = input.
iconoclast

7
@iconclast, một lý do tôi gặp phải là nếu bạn xây dựng các bản phân phối bao gồm cả tệp bó Windows và tập lệnh shell Unix. Bạn muốn sử dụng đúng dòng kết thúc trong từng trường hợp và điều này khó thực hiện hơn nếu Git đang làm xáo trộn mọi thứ xung quanh ngay cả khi bạn rõ ràng đặt chúng theo cách này hay cách khác.
user1809090

Câu trả lời:


227

Những lý do cụ thể duy nhất để đặt autocrlfthành truelà:

  • tránh git statushiển thị tất cả các tệp của bạn modifiedvì chuyển đổi EOL tự động được thực hiện khi sao chép repo EOL Git dựa trên Unix sang Windows ( ví dụ: xem vấn đề 83 )
  • các công cụ mã hóa của bạn bằng cách nào đó phụ thuộc vào kiểu EOL gốc có trong tệp của bạn:

Trừ khi bạn có thể thấy điều trị đặc hiệu mà phải đối phó với EOL bản xứ, bạn là tốt hơn hết để lại autocrlfchofalse ( git config --global core.autocrlf false).

Lưu ý rằng cấu hình này sẽ là cấu hình cục bộ (vì cấu hình không được đẩy từ repo sang repo)

Nếu bạn muốn cấu hình giống nhau cho tất cả người dùng nhân bản repo đó, hãy xem " Chiến lược xử lý tốt nhất CRLFvới git là gì? ", Sử dụng textthuộc tính trong .gitattributestệp .

Thí dụ:

*.vcproj    text eol=crlf
*.sh        text eol=lf

Lưu ý: bắt đầu git 2.8 (tháng 3 năm 2016), các dấu hợp nhất sẽ không còn giới thiệu kết thúc dòng hỗn hợp (LF) trong tệp CRLF.
Xem " Tạo Git sử dụng CRLF trên dòng <<<<<<< ĐẦU TIẾT "


5
@VonC Cảm ơn! Điều đó giúp tôi cảm thấy tự tin hơn rằng nó an toàn cho tôi sử dụng autocrlf=false. Không quan tâm, bạn có biết tại sao git vẫn chuyển đổi eol ngay cả khi bạn đã đặt autocrlf thành false không?
Giàu

14
@VonC: Tôi không nghĩ câu trả lời này là đúng. Sử dụng core.autocrlf = true trên Windows hoạt động như mong đợi. Tất cả các tệp từ repo (cần có kết thúc dòng LF trong kịch bản này) được chuyển đổi thành kết thúc dòng CRLF khi thanh toán sang PC Windows. Tất cả các tệp được chuyển đổi trở lại kết thúc dòng LF trên cam kết từ PC Windows. Cách để gặp rắc rối là kiểm tra ban đầu cho PC Windows với cài đặt core.autocrlf sai (điều này hoàn toàn quá dễ thực hiện).
Michael Maddox

3
@Michael Vì vậy, trong trường hợp đó là lý do duy nhất để không sử dụng core.autocrlf=falsetrong kịch bản của tôi là nếu tôi có một số công cụ / trình chỉnh sửa sẽ bị nhầm lẫn bởi các kết thúc dòng?
Giàu

49
Tôi chắc chắn sẽ sử dụng false, tôi chưa bao giờ là một fan hâm mộ lớn của những thứ tự động hoặc ma thuật xảy ra trong nền. Chỉ cần sử dụng \nUTF-8ở mọi nơi và bạn sẽ ổn thôi. Nếu một số người đứng đầu không hiểu rằng có những quy ước và quy tắc và quên sử dụng UTF-8hoặc \n, thì ai đó sẽ chuyển đổi chúng bằng tay và tát vào mặt anh ta.
Tháp

5
@ Pauld'Aoust Tôi vẫn muốn chỉ định loại tệp cần CRLF đó thông qua core.eolcác thuộc tính trong .gitattributestệp, thay vì sử dụng core.autocrlfcài đặt chung này áp dụng bừa bãi cho tất cả các tệp.
VonC

40

Tôi là một nhà phát triển .NET và đã sử dụng Git và Visual Studio trong nhiều năm. Khuyến nghị mạnh mẽ của tôi là đặt kết thúc dòng thành đúng. Và làm điều đó sớm nhất có thể trong vòng đời của Kho lưu trữ của bạn.

Điều đó đang được nói, tôi ghét rằng Git thay đổi kết thúc dòng của tôi. Kiểm soát nguồn chỉ nên lưu và truy xuất công việc tôi làm, KHÔNG nên sửa đổi nó. Không bao giờ. Nhưng nó làm.

Điều gì sẽ xảy ra nếu bạn không đặt mọi nhà phát triển thành đúng, cuối cùng thì MỘT nhà phát triển sẽ được đặt thành đúng. Điều này sẽ bắt đầu thay đổi kết thúc dòng của tất cả các tệp của bạn thành LF trong repo của bạn. Và khi người dùng đặt thành kiểm tra sai, Visual Studio sẽ cảnh báo bạn và yêu cầu bạn thay đổi chúng. Bạn sẽ có 2 điều xảy ra rất nhanh. Một, bạn sẽ nhận được càng nhiều những cảnh báo đó, nhóm của bạn càng lớn bạn càng nhận được nhiều. Điều thứ hai, và điều tồi tệ hơn là nó sẽ cho thấy rằng mọi dòng của mỗi tệp được sửa đổi đã bị thay đổi (bởi vì kết thúc dòng của mỗi dòng sẽ được thay đổi bởi người thực sự). Cuối cùng, bạn sẽ không thể theo dõi các thay đổi trong repo của mình một cách đáng tin cậy nữa. Thật dễ dàng và sạch sẽ hơn để làm cho mọi người giữ đúng, hơn là cố gắng giữ cho mọi người sai. Thật kinh khủng khi sống với thực tế là kiểm soát nguồn đáng tin cậy của bạn đang làm điều gì đó không nên. Không bao giờ.


Công ty của tôi đủ nhỏ để chúng tôi có thể dễ dàng ủy quyền rằng sai được sử dụng ở mọi nơi và tôi đã nghĩ rằng các công ty lớn hơn có thể thực hiện điều này thông qua chính sách, nhưng tôi đoán đây là một lý do chính đáng để sử dụng "đúng", vì vậy tôi ủng hộ dù sao. Cảm ơn!
Giàu có

1
Vấn đề với việc thực hiện điều này với một chính sách (tệp được thi hành) là trên máy tính windows, bạn có thể có tệp cấu hình cục bộ, toàn cục và ẩn (ProgramData / Git / Confg). Bạn có thể thực thi cục bộ bằng cách kiểm tra nó vào repo, nhưng các tệp toàn cầu VÀ ẩn được ưu tiên. Ngoài ra có thể có địa phương và toàn cầu (hoặc ẩn) là khác nhau. Nếu có, chúng sẽ xung đột với nhau trên máy CÙNG gây ra lỗi kết thúc dòng không có lỗi. Đây là một nỗi đau để theo dõi. :(
JGTaylor

7
chính xác những gì tôi nghĩ Đây không phải là công việc của một điều khiển nguồn để gây rối với các tệp mã khi nó vừa ý. kết thúc dòng chỉ đơn giản là một mối quan tâm của các công cụ chỉnh sửa, không có gì hơn.
Tuncay Göncüoğlu

6
Nếu dự án của bạn chỉ dành cho Windows thì không có vấn đề gì. Tuy nhiên, nếu bạn hoặc đồng nghiệp của bạn làm việc trên nền tảng * nix thì "khuyến nghị mạnh mẽ" của bạn sẽ gây ra vấn đề. Hãy thử chạy một tập lệnh bash, perl hoặc python với shebang kết thúc bằng \r\nvà bạn sẽ thấy.
phuclv

6
Tình huống mà bạn mô tả không phải là vấn đề của GIT, hãy đặt cài đặt thành FALSE như thường lệ và nó sẽ biến mất. Instad, đó là một vấn đề trong công việc nhóm. "Cuối cùng một bộ phát triển" nghĩa là truegì? Tại sao bạn lại cho phép họ ở nơi đầu tiên? khi bạn thiết lập chúng để truy cập git repo, thì giống như bạn không cho phép gây ô nhiễm một số khu vực nhất định với các lang khác nhau (vì vậy bất kỳ ai làm việc trên đó đều có thể đọc nó), hoặc giống như bạn giữ các nhánh / sáp nhập / nổi loạn / v.v. Chính sách, họ sẽ nhận được một quy tắc rõ ràng: đặt đúng crlf.
quetzalcoatl

12

Cập nhật 2 :

Xcode 9 dường như có một "tính năng" trong đó nó sẽ bỏ qua các kết thúc dòng hiện tại của tệp và thay vào đó chỉ sử dụng cài đặt kết thúc dòng mặc định của bạn khi chèn các dòng vào một tệp, dẫn đến các tệp có kết thúc dòng hỗn hợp.

Tôi khá chắc chắn rằng lỗi này không tồn tại trong Xcode 7; không chắc chắn về Xcode 8. Tin tốt là nó dường như được sửa trong Xcode 10.

Trong thời gian tồn tại, lỗi này đã gây ra một số ít sự vui nhộn trong cơ sở mã mà tôi đề cập đến trong câu hỏi (mà ngày nay sử dụng autocrlf=false), và dẫn đến nhiều thông điệp cam kết "EOL" và cuối cùng là tôi viết một git pre-commithook để kiểm tra cho / ngăn chặn giới thiệu kết thúc dòng hỗn hợp.

Cập nhật :

Lưu ý: Như VonC đã lưu ý, bắt đầu từ Git 2.8, các điểm đánh dấu hợp nhất sẽ không giới thiệu các kết thúc dòng kiểu Unix cho tệp kiểu Windows .

Bản gốc :

Một trục trặc nhỏ mà tôi nhận thấy với thiết lập này là khi có xung đột hợp nhất, các dòng git thêm vào để đánh dấu sự khác biệt không có kết thúc dòng Windows, ngay cả khi phần còn lại của tệp có và bạn có thể kết thúc với một tệp có kết thúc dòng hỗn hợp, ví dụ:

// Some code<CR><LF>
<<<<<<< Updated upstream<LF>
// Change A<CR><LF>
=======<LF>
// Change B<CR><LF>
>>>>>>> Stashed changes<LF>
// More code<CR><LF>

Điều này không gây ra cho chúng tôi bất kỳ vấn đề nào (tôi tưởng tượng bất kỳ công cụ nào có thể xử lý cả hai loại kết thúc dòng cũng sẽ xử lý hợp lý với các kết thúc dòng hỗn hợp - chắc chắn là tất cả những công cụ chúng tôi sử dụng), nhưng đó là điều cần chú ý.

Một điều khác * chúng tôi đã tìm thấy, là khi sử dụng git diffđể xem các thay đổi đối với tệp có kết thúc dòng Windows, các dòng đã được thêm sẽ hiển thị lợi nhuận vận chuyển của họ, do đó:

    // Not changed

+   // New line added in^M
+^M
    // Not changed
    // Not changed

* Nó không thực sự xứng đáng với thuật ngữ: "vấn đề".


2
NB Khi Visual Studio gặp một tệp như vậy, nó cung cấp để bình thường hóa các kết thúc dòng cho bạn. Chọn các kết thúc dòng Windows hoặc chọn không bình thường hóa các kết thúc dòng hoạt động tốt (vì VS vẫn hiển thị chính xác các dòng vi phạm sẽ bị xóa sau khi xung đột đã được giải quyết).
Giàu

2
Thật không may, phiên bản công ty kiểm soát nazis không đồng ý với nó (LF trên các dấu hiệu xung đột hợp nhất) không phải là một vấn đề.
Ilia G

1
Tôi đồng ý rằng LF về đánh dấu xung đột hợp nhất không phải là một vấn đề. Những dòng đó không nên được cam kết với repo nào.
cướp

1
Lưu ý: bắt đầu git 2.8 (tháng 3 năm 2016), các điểm đánh dấu hợp nhất sẽ thực sự có kết thúc dòng CRLF. Xem stackoverflow.com/a/35474954/6309
VonC
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.