Chiến lược xử lý CRLF (trả lại vận chuyển, cấp dữ liệu) tốt nhất với Git là gì?


598

Tôi đã thử cam kết các tệp với dòng kết thúc CRLF, nhưng không thành công.

Tôi đã dành cả một ngày làm việc trên máy tính Windows của mình để thử các chiến lược khác nhau và gần như bị thu hút khi ngừng sử dụng Git và thay vào đó hãy thử Mercurial .

Vui lòng chỉ chia sẻ một thực hành tốt nhất cho mỗi câu trả lời.

Câu trả lời:


753

Gần bốn năm sau khi hỏi câu hỏi này, cuối cùng tôi đã tìm thấy một câu trả lời hoàn toàn thỏa mãn tôi !

Xem chi tiết trong github: hướng dẫn trợ giúp về Xử lý kết thúc dòng .

Git cho phép bạn đặt thuộc tính kết thúc dòng cho repo trực tiếp bằng thuộc tính văn bản trong .gitattributestệp. Tập tin này được cam kết vào repo và ghi đè core.autocrlfcài đặt, cho phép bạn đảm bảo hành vi nhất quán cho tất cả người dùng bất kể cài đặt git của họ.

Và như vậy

Ưu điểm của việc này là cấu hình cuối dòng của bạn hiện đang di chuyển với kho lưu trữ của bạn và bạn không cần phải lo lắng về việc liệu các cộng tác viên có cài đặt toàn cầu phù hợp hay không.

Đây là một ví dụ về một .gitattributestập tin

# Auto detect text files and perform LF normalization
*        text=auto

*.cs     text diff=csharp
*.java   text diff=java
*.html   text diff=html
*.css    text
*.js     text
*.sql    text

*.csproj text merge=union
*.sln    text merge=union eol=crlf

*.docx   diff=astextplain
*.DOCX   diff=astextplain

# absolute paths are ok, as are globs
/**/postinst* text eol=lf

# paths that don't start with / are treated relative to the .gitattributes folder
relative/path/*.txt text eol=lf

Có một bộ sưu tập thuận tiện sẵn sàng để sử dụng các tệp .gitattribut cho các ngôn ngữ lập trình phổ biến nhất. Thật hữu ích để giúp bạn bắt đầu.

Khi bạn đã tạo hoặc điều chỉnh .gitattributes, bạn nên thực hiện tái chuẩn hóa một lần và tất cả các dòng kết thúc .

Lưu ý rằng ứng dụng GitHub Desktop có thể đề xuất và tạo .gitattributestệp sau khi bạn mở repo Git của dự án trong ứng dụng. Để thử điều đó, hãy nhấp vào biểu tượng bánh răng (ở góc trên bên phải)> Cài đặt kho lưu trữ ...> Kết thúc dòng và thuộc tính. Bạn sẽ được yêu cầu thêm đề xuất .gitattributesvà nếu bạn đồng ý, ứng dụng cũng sẽ thực hiện chuẩn hóa tất cả các tệp trong kho lưu trữ của bạn.

Cuối cùng, bài viết Mind the End of Your Line cung cấp thêm thông tin cơ bản và giải thích cách Git đã phát triển về các vấn đề hiện tại. Tôi xem xét yêu cầu đọc này .

Có lẽ bạn đã có người dùng trong nhóm của mình sử dụng EGit hoặc JGit (các công cụ như Eclipse và TeamCity sử dụng chúng) để cam kết các thay đổi của họ. Sau đó, bạn không gặp may, vì @gatinueta đã giải thích trong bình luận của câu trả lời này:

Cài đặt này sẽ không đáp ứng hoàn toàn cho bạn nếu bạn có người làm việc với Egit hoặc JGit trong nhóm của mình, vì các công cụ đó sẽ bỏ qua .gitattribut và vui vẻ kiểm tra các tệp CRLF https://bugs.eclipse.org/bugs/show_orms.cgi? id = 342372

Một mẹo có thể là để họ cam kết thay đổi của họ trong một khách hàng khác, theo SourceTree . Sau đó, nhóm của chúng tôi đã ưu tiên công cụ đó cho EGit của Eclipse trong nhiều trường hợp sử dụng.

Ai nói phần mềm là dễ? : - /


7
Muốn chia sẻ Windows .gitattributes?
Đại tá Panic

Làm thế nào bạn có thể thấy .gitattributesGitHub cho Windows gợi ý gì cho dự án của bạn? Tôi đã cài đặt GitHub cho Windows, khởi động phiên bản GUI và không thể tìm thấy bất kỳ tùy chọn nào liên quan đến các .gitattributesđề xuất.
JLDiaz

4
Thiết lập này sẽ không làm bạn hài lòng hoàn toàn nếu bạn có những người làm việc với Egit trong nhóm của bạn, vì egit sẽ chỉ cần bỏ qua .gitattributes và vui vẻ nhận phòng CRLF file bugs.eclipse.org/bugs/show_bug.cgi?id=342372
gatinueta

19
Đối với Windows, tôi thường có xu hướng thiết lập toàn cầu core.autocrlf = false- Tôi thích LF ở mọi nơi, nhưng một số công cụ Windows như Visual Studio nhấn mạnh vào kết thúc CRLF trong một số tệp nhất định (và thậm chí trộn chúng trong một vài ..); không kết thúc dòng munging là lựa chọn an toàn nhất. Nếu bạn biết bạn đang làm gì, có lẽ tôi sẽ sử dụng core.autocrlf = inputvà đưa ra ngoại lệ cho các dự án trên Windows mà bạn biết là nhạy cảm với kết thúc dòng. Như những người khác chỉ ra, mọi trình soạn thảo văn bản đàng hoàng đều hỗ trợ các kết thúc của LF ngay bây giờ. Tôi thực sự nghĩ rằng core.autocrlf = truecó thể gây ra nhiều rắc rối hơn nó ngăn chặn.
Adrian

1
@gatinueta Để cụ thể hơn, đó là vấn đề của JGit. Có nghĩa là TeamCity, cũng sử dụng JGit, ngay lập tức bỏ qua .gitattribut.
sdds

122

Đừng chuyển đổi kết thúc dòng. Đây không phải là công việc của VCS để giải thích dữ liệu - chỉ cần lưu trữ và phiên bản nó. Mỗi trình soạn thảo văn bản hiện đại có thể đọc cả hai loại kết thúc dòng.


25
Biệt phái. Nếu bạn gặp vấn đề với các kết thúc dòng không nhất quán, giải pháp tốt nhất là hét vào bất cứ ai sử dụng các cài đặt trình chỉnh sửa sai cho đến khi họ khắc phục nó.

136
Không đồng ý. Nguồn cấp dữ liệu gốc trên tất cả các nền tảng là một tiện lợi.
Jonas Byström

25
Visual Studio là một PITA khi nói đến bất cứ thứ gì khác ngoài CRLF.
Brett Ryan

32
Git có một tùy chọn không chuyển đổi kết thúc dòng, đó là autocrlf = false và trừ khi bạn đang thực hiện phát triển đa nền tảng, như nói Mono, tốt nhất là trái thành sai khi chạy trong Windows và được đặt thành true nếu bạn sẽ phát triển nguồn mở cho Mono.
Chris Nicola

24
Vấn đề với kết thúc dòng là tính toán khác biệt chính xác. Vì vậy, câu trả lời là sai và sai.
cos

84

Bạn hầu như luôn muốn autocrlf=inputtrừ khi bạn thực sự biết những gì bạn đang làm.

Một số bối cảnh bổ sung dưới đây:

Nó nên là core.autocrlf=truenếu bạn thích kết thúc DOS hoặc core.autocrlf=inputnếu bạn thích unix-newlines. Trong cả hai trường hợp, kho lưu trữ Git của bạn sẽ chỉ có LF, đó là Điều đúng. Đối số duy nhất core.autocrlf=falselà heuristic tự động có thể phát hiện không chính xác một số nhị phân dưới dạng văn bản và sau đó ô của bạn sẽ bị hỏng. Vì vậy, core.safecrlftùy chọn đã được giới thiệu để cảnh báo người dùng nếu thay đổi không thể đảo ngược xảy ra. Trên thực tế, có hai khả năng thay đổi không thể đảo ngược - kết thúc dòng hỗn hợp trong tệp văn bản, trong chuẩn hóa này là mong muốn, vì vậy cảnh báo này có thể bị bỏ qua hoặc (rất khó) rằng Git đã phát hiện không chính xác tệp nhị phân của bạn dưới dạng văn bản. Sau đó, bạn cần sử dụng các thuộc tính để nói với Git rằng tệp này là nhị phân.

Đoạn văn trên ban đầu được lấy từ một chủ đề trên gmane.org, nhưng nó đã đi xuống.


31
Tại sao nó là "Điều đúng"?
Artem Tikhomirov

35
core.autocrlf = true là một ý tưởng tồi tệ. Tôi không gặp vấn đề gì với tùy chọn đó, ngoài ra bạn phải nhớ đặt nó bất cứ khi nào bạn sao chép kho lưu trữ.
Luís Oliveira

28
KHÔNG sử dụng autocrlf = true trừ khi bạn biết bạn đang làm gì. Nếu bạn phát triển trong DOS / Win thì autocrlf = false sẽ giữ kết thúc giống nhau giữa điều khiển từ xa và cục bộ và là lựa chọn tốt nhất trong hầu hết mọi tình huống.
Chris Nicola

13
@Chris - Điều gì xảy ra nếu nhà phát triển của bạn có cửa sổ và các dự án đa nền tảng trong đó một số nhà phát triển đa nền tảng hoạt động trên OSX hoặc Linux? Không phải là tùy chọn tốt nhất sau đó là autocrlf = true?
Brett Ryan

20
Nâng cao, có đặt phòng. Đoạn giới thiệu là không có ích. core.autocrlf=inputlà câu trả lời kinh điển. Đối với hầu hết các trường hợp sử dụng, core.autocrlf=truecore.autocrlf=falsequá nhiệt tình (tất nhiên là ... theo cách ngược lại nhưng cũng không kém phần khủng khiếp) và do đó thực chất là phá hoại. "Git cho Windows" thực sự đã được phát hành với "Checkout như hiện tại, cam kết các kết thúc dòng theo kiểu Unix" (nghĩa là core.autocrlf=input) như chiến lược dòng mới mặc định của nó. Nó đã không. Vì vậy, ở đây chúng tôi ở đây - trong năm 2015 - vẫn không ngừng tranh luận về điều này.
Cà ri Cecil

58

Hai chiến lược thay thế để thống nhất về kết thúc dòng trong môi trường hỗn hợp (Microsoft + Linux + Mac):

A. Toàn cầu trên tất cả các thiết lập kho

1) Chuyển đổi tất cả thành một định dạng

find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'

2) Đặt core.autocrlfthành inputtrên Linux / UNIX hoặc truetrên MS Windows (kho lưu trữ hoặc toàn cầu)

git config --global core.autocrlf input

3) [Tùy chọn] được đặt core.safecrlfthành true(dừng) hoặc warn(hát :) để thêm bảo vệ so sánh nếu chuyển đổi dòng mới bị đảo ngược sẽ dẫn đến cùng một tệp

git config --global core.safecrlf true


B. Hoặc mỗi thiết lập kho lưu trữ

1) Chuyển đổi tất cả thành một định dạng

find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'

2) thêm .gitattributestập tin vào kho lưu trữ của bạn

echo "* text=auto" > .gitattributes
git add .gitattributes
git commit -m 'adding .gitattributes for unified line-ending'

Đừng lo lắng về các tệp nhị phân của bạn - Git nên đủ thông minh về chúng.


Tìm hiểu thêm về các biến safecrlf / autocrlf


5
cách tiếp cận toàn cầu == đặt và quên cho tất cả các repos so với mỗi repo == không yêu cầu người khác thay đổi cấu hình toàn cầu của họ.
lukmdo

4
dos2unixlà một công cụ dòng lệnh tùy thuộc vào hệ thống mà bạn có thể phải cài đặt bổ sung
lukmdo

2
Chúng không độc quyền, bạn có thể sử dụng cả hai cách tiếp cận cùng một lúc. Ngoài ra, hãy cẩn thận khi sử dụng dos2unix- có nguy cơ bị hỏng.git/index và chúng tôi không cần phải áp dụng nó cho mọi tệp. Tốt hơn là sử dụng một cái gì đó như find ./ -name "*.html"và chỉ định những tập tin bạn muốn áp dụng nó.
cregox

6
CẢNH BÁO: trước khi chạy các finddòng, hãy lưu ý: phiên bản dos2unixđi kèm với Git cho Windows có hành vi đặc biệt (ngu ngốc và nguy hiểm IMO), không có đối số: thay vì chuyển sang UNIX, nó thay đổi định dạng dòng mới (DOS <-> UNIX )
leonbloy

2
Và một cảnh báo khác: đừng DOS2UNIX thư mục .git của bạn. Chỉ cần nói.
hakre

10

Hãy thử đặt core.autocrlftùy chọn cấu hình thành true. Cũng có một cái nhìn vào các core.safecrlftùy chọn.

Trên thực tế có vẻ như core.safecrlfcó thể đã được đặt trong kho lưu trữ của bạn, bởi vì (nhấn mạnh của tôi):

Nếu đây không phải là trường hợp cho cài đặt hiện tại của core.autocrlf, git sẽ từ chối tệp .

Nếu đây là trường hợp, thì bạn có thể muốn kiểm tra xem trình soạn thảo văn bản của bạn có được cấu hình để sử dụng kết thúc dòng một cách nhất quán không. Bạn có thể sẽ gặp vấn đề nếu một tệp văn bản chứa hỗn hợp các kết thúc dòng LF và CRLF.

Cuối cùng, tôi cảm thấy rằng khuyến nghị chỉ đơn giản là "sử dụng những gì bạn đã đưa ra" và sử dụng các dòng kết thúc của LF trên Windows sẽ gây ra nhiều vấn đề hơn nó giải quyết. Git có các tùy chọn ở trên để cố gắng xử lý các kết thúc dòng một cách hợp lý, vì vậy sẽ rất hợp lý khi sử dụng chúng.


1
Sẽ không tốt hơn nếu sử dụng cài đặt rộng kho lưu trữ thông qua tệp .gitattribut? Chỉ tự hỏi: thật bất tiện khi buộc mọi người dùng phải quan tâm đến cài đặt kết thúc dòng trên máy của mình ... Hay có những nhược điểm khác?
đào tạo

10

Việc sử dụng core.autocrlf=falseđã dừng tất cả các tệp khỏi bị đánh dấu cập nhật ngay sau khi tôi kiểm tra chúng trong dự án Visual Studio 2010 của tôi . Hai thành viên khác của nhóm phát triển cũng đang sử dụng các hệ thống Windows nên môi trường hỗn hợp không hoạt động, tuy nhiên các cài đặt mặc định đi kèm với kho lưu trữ luôn đánh dấu tất cả các tệp là được cập nhật ngay sau khi nhân bản.

Tôi đoán điểm mấu chốt là tìm ra cài đặt CRLF nào hoạt động cho môi trường của bạn. Đặc biệt là trong nhiều kho lưu trữ khác trên cài đặt hộp Linux của chúng tôi autocrlf = truetạo ra kết quả tốt hơn.

Hơn 20 năm sau và chúng ta vẫn đang đối phó với sự chênh lệch kết thúc dòng giữa các hệ điều hành ... thật đáng buồn.


31
@ cam80, sự chênh lệch là không may, nhưng không có lý do gì để gọi đó là lỗi của Windows. Có lẽ chỉ có ý nghĩa từ quan điểm tối giản; nhưng CRLF có ý nghĩa hơn dựa trên ý nghĩa của CR và LF. "Vận chuyển trở lại" có nghĩa là trở về đầu dòng; "nguồn cấp dữ liệu" có nghĩa là di chuyển thẳng xuống dòng tiếp theo, thay vì đến đầu dòng tiếp theo. Từ quan điểm ngữ nghĩa, Windows đúng hơn khi có cả hai: di chuyển trở lại từ đầu (CR) và sau đó xuống một dòng (LF).
Ryan Lundy

40
@Kyralessa "đúng hơn" khi vẫn giả vờ rằng máy tính là một máy đánh chữ, nhưng không phải vậy, btw. Việc duy trì sự tương tự của máy đánh chữ sẽ không có ý nghĩa gì vì đây không phải là điều mà người dùng cuối sẽ phải đối phó và hai ký tự thay vì một ký tự là vô nghĩa.
jpswain

1
Đến bữa tiệc muộn vài năm, nhưng bạn đã bỏ qua thực tế rằng CR và LF là công cụ định vị con trỏ. "CR" cũng có thể là "Trả lại con trỏ" tại thời điểm này trong lịch sử. Nếu tôi muốn con trỏ trở về đầu dòng, tôi sẽ bảo ứng dụng làm điều đó. Nếu không, nó cần ở lại nơi tôi đặt nó.
EKW

2
Ngoài ra, nếu CRLF "chính xác hơn" bởi vì một dòng mới textfile thực sự vừa là "di chuyển một hàng xuống" và "di chuyển đến đầu dòng", thì CR sẽ khiến trình soạn thảo văn bản ghi đè lên một dòng với dòng sau. Tôi biết không có biên tập viên nào thực sự hỗ trợ điều này, có nghĩa là nhu cầu thể hiện cả CRLF và CR là những thứ khác nhau, không thực sự tồn tại.
avl_sweden

@avl_sweden Đó là hành vi rất phổ biến trước DOS và vì Microsoft cho rằng khả năng tương thích là quan trọng, nên nó đã nói lên điều đó kể từ đó. Đó cũng là cách tiêu chuẩn ở Hoa Kỳ (với tư cách là ASA) - ISO cho phép cả CR + LF và LF (một lần nữa, DOS tuân thủ các tiêu chuẩn); trong cả hai trường hợp, kể từ những năm sáu mươi. Multics (tiền thân Unix) hỗ trợ CR cho đậm / đình công. Nhiều ứng dụng hiện nay (bao gồm các tính năng "phân chia theo dòng" của .NET) tìm kiếm một trong ba tính năng (CR đơn độc, đơn độc LF, CRLF) và coi mỗi trong số chúng là dòng cuối. Mặc dù vậy, nhiều ứng dụng vẫn bị nhầm lẫn bởi các kết thúc dòng hỗn hợp trong một tệp.
Luaan

7

Đây là hai tùy chọn cho người dùng WindowsVisual Studio chia sẻ mã với người dùng Mac hoặc Linux . Đối với một lời giải thích mở rộng, đọc hướng dẫn gitattribut .

* văn bản = tự động

Trong .gitattributestập tin repo của bạn thêm:

*   text=auto

Điều này sẽ bình thường hóa tất cả các tệp có LFkết thúc dòng trong repo.

Và tùy thuộc vào hệ điều hành ( core.eolcài đặt) của bạn, các tệp trong cây làm việc sẽ được chuẩn hóa thành LFcác hệ thống dựa trên Unix hoặc CRLFcho các hệ thống Windows.

Đây là cấu hình mà Microsoft .NET repos sử dụng.

Thí dụ:

Hello\r\nWorld

Sẽ được chuẩn hóa trong repo luôn như sau:

Hello\nWorld

Khi thanh toán, cây làm việc trong Windows sẽ được chuyển đổi thành:

Hello\r\nWorld

Khi thanh toán, cây làm việc trong Mac sẽ được để lại là:

Hello\nWorld

Lưu ý: Nếu repo của bạn đã chứa các tệp không được chuẩn hóa, git statussẽ hiển thị các tệp này dưới dạng sửa đổi hoàn toàn vào lần tiếp theo bạn thực hiện bất kỳ thay đổi nào đối với chúng và việc người dùng khác có thể hợp nhất các thay đổi của chúng sau này. Xem làm mới một kho lưu trữ sau khi thay đổi kết thúc dòng để biết thêm thông tin.

core.autocrlf = đúng

Nếu textkhông được chỉ định trong .gitattributestệp, Git sử dụng core.autocrlfbiến cấu hình để xác định xem tệp có nên được chuyển đổi không.

Đối với người dùng Windows, git config --global core.autocrlf truelà một lựa chọn tuyệt vời vì:

  • Các tệp được chuẩn hóa thành các LFkết thúc dòng chỉ khi được thêm vào repo. Nếu có các tệp không được chuẩn hóa trong repo, cài đặt này sẽ không chạm vào chúng.
  • Tất cả các tệp văn bản được chuyển đổi thành CRLFkết thúc dòng trong thư mục làm việc.

Vấn đề với phương pháp này là:

  • Nếu bạn là người dùng Windows autocrlf = input, bạn sẽ thấy một loạt các tệp có LFkết thúc dòng. Không phải là mối nguy hiểm cho phần còn lại của đội, bởi vì các cam kết của bạn sẽ vẫn được bình thường hóa với các LFkết thúc dòng.
  • Nếu bạn là người dùng Windows core.autocrlf = false, bạn sẽ thấy một loạt các tệp có LFkết thúc dòng và bạn có thể giới thiệu các tệp có CRLFkết thúc dòng vào repo.
  • Hầu hết người dùng Mac sử dụng autocrlf = inputvà có thể nhận các tệp có CRLFkết thúc tệp, có thể từ người dùng Windows với core.autocrlf = false.

1
Lệnh của bạn cho người dùng windows nói git config --global core.autocrl true. Bạn có ý nghĩa git config --global core.autocrlf true.
JellicleCat

6

--- CẬP NHẬT 3 --- (không xung đột với CẬP NHẬT 2)

Xem xét trường hợp người dùng windows thích làm việc trên CRLFvà người dùng linux / mac thích làm việc trên LFcác tệp văn bản. Cung cấp câu trả lời từ quan điểm của một người duy trì kho lưu trữ :

Đối với tôi, chiến lược tốt nhất (những vấn đề ít hơn để giải quyết) là: giữ tất cả các file văn bản với LFrepo git bên ngay cả khi bạn đang làm việc trên một dự án cửa sổ-chỉ. Sau đó, cho phép khách hàng tự do làm việc theo kiểu kết thúc dòng theo sở thích của họ , miễn là họ chọn một core.autocrlfgiá trị thuộc tính sẽ tôn trọng chiến lược của bạn (LF trên repo) trong khi sắp xếp các tệp để cam kết.

Dàn dựng là điều mà nhiều người nhầm lẫn khi cố gắng hiểu cách các chiến lược dòng mới hoạt động. Điều cần thiết là hủy bỏ các điểm sau đây trước khi chọn giá trị chính xác cho thuộc core.autocrlftính:

  • Thêm một tệp văn bản cho cam kết ( dàn nó) giống như sao chép tệp vào một nơi khác trong .git/thư mục con với các kết thúc dòng được chuyển đổi (tùy thuộc vào core.autocrlfgiá trị trên cấu hình máy khách của bạn). Tất cả điều này được thực hiện tại địa phương.
  • cài đặt core.autocrlfgiống như cung cấp câu trả lời cho câu hỏi (chính xác cùng một câu hỏi trên tất cả các hệ điều hành):
    • "Git-client a. Chuyển đổi LF-thành-CRLF khi thanh toán (kéo) thay đổi repo từ xa hoặc b. Chuyển đổi CRLF-thành-LF khi thêm tệp cho cam kết? " Và các câu trả lời có thể có (giá trị) Chúng tôi:
    • false:" không làm ở trên ",
    • input:" chỉ làm b "
    • true: " làm a và b "
    • lưu ý rằng KHÔNG CÓ " chỉ làm một "

May mắn thay

  • git client mặc định (windows : core.autocrlf: true, linux / mac core.autocrlf: false:) sẽ tương thích với chiến lược chỉ có repo của LF .
    Ý nghĩa : các máy khách windows theo mặc định sẽ chuyển đổi thành CRLF khi kiểm tra kho lưu trữ và chuyển đổi thành LF khi thêm xác nhận. Và các máy khách linux sẽ mặc định không thực hiện bất kỳ chuyển đổi nào. Về lý thuyết này giữ repo của bạn chỉ lf.

Không may:

  • Có thể có các máy khách GUI không tôn trọng core.autocrlfgiá trị git
  • Có thể có những người không sử dụng giá trị để tôn trọng chiến lược lf-repo của bạn. Ví dụ, họ sử dụng core.autocrlf=falsevà thêm một tệp với CRLF để xác nhận.

Để phát hiện các tệp văn bản không phải lf ASAP được cam kết bởi các máy khách ở trên, bạn có thể làm theo những gì được mô tả trên --- update 2 ---: ( git grep -I --files-with-matches --perl-regexp '\r' HEAD, trên một máy khách được biên dịch bằng cách sử dụng: --with-libpcreflag)

Và đây là cái bẫy : . Tôi với tư cách là người duy trì repo giữ git.autocrlf=inputđể tôi có thể sửa bất kỳ tệp cam kết sai nào chỉ bằng cách thêm chúng một lần nữa cho cam kết. Và tôi cung cấp một văn bản cam kết: "Sửa các tệp cam kết sai".

Theo như .gitattributesđược học hỏi. Tôi không tin vào điều đó, vì có nhiều khách hàng ui không hiểu nó. Tôi chỉ sử dụng nó để cung cấp gợi ý cho các tệp văn bản và tệp nhị phân và có thể gắn cờ một số tệp đặc biệt mà mọi nơi sẽ giữ cùng một kết thúc dòng:

*.java          text !eol # Don't do auto-detection. Treat as text (don't set any eol rule. use client's)
*.jpg           -text     # Don't do auto-detection. Treat as binary
*.sh            text eol=lf # Don't do auto-detection. Treat as text. Checkout and add with eol=lf
*.bat           text eol=crlf # Treat as text. Checkout and add with eol=crlf

Câu hỏi: Nhưng tại sao chúng ta quan tâm đến tất cả trong chiến lược xử lý dòng mới?

Trả lời: Để tránh một cam kết thay đổi một chữ cái, hãy xuất hiện dưới dạng thay đổi 5000 dòng , chỉ vì ứng dụng khách thực hiện thay đổi tự động chuyển đổi toàn bộ tệp từ crlf sang lf (hoặc ngược lại) trước khi thêm cam kết. Điều này có thể khá đau đớn khi có một giải quyết xung đột liên quan. Hoặc trong một số trường hợp, nó có thể là nguyên nhân của những xung đột không hợp lý.


--- CẬP NHẬT 2 ---

Các dahaults của git client sẽ hoạt động trong hầu hết các trường hợp. Ngay cả khi bạn chỉ có windows chỉ có máy khách, linux chỉ có máy khách hoặc cả hai. Đó là:

  • windows: core.autocrlf=true có nghĩa là chuyển đổi dòng thành CRLF khi thanh toán và chuyển đổi dòng thành LF khi thêm tệp.
  • linux: core.autocrlf=input có nghĩa là không chuyển đổi các dòng khi thanh toán (không cần thiết vì các tệp dự kiến ​​sẽ được cam kết với LF) và chuyển đổi các dòng thành LF (nếu cần) khi thêm tệp. ( - update3 - : Có vẻ như đây là falsemặc định, nhưng một lần nữa nó vẫn ổn)

Các tài sản có thể được thiết lập trong phạm vi khác nhau. Tôi sẽ đề nghị thiết lập rõ ràng trong --globalphạm vi, để tránh một số vấn đề IDE được mô tả ở cuối.

git config core.autocrlf
git config --global core.autocrlf
git config --system core.autocrlf
git config --local core.autocrlf
git config --show-origin core.autocrlf

Ngoài ra, tôi sẽ không khuyến khích sử dụng trên các cửa sổ git config --global core.autocrlf false (trong trường hợp bạn chỉ có các máy khách của windows) trái ngược với những gì được đề xuất cho tài liệu git . Đặt thành false sẽ cam kết các tệp với CRLF trong repo. Nhưng thực sự không có lý do. Bạn không bao giờ biết liệu bạn sẽ cần chia sẻ dự án với người dùng linux hay không. Thêm vào đó là thêm một bước cho mỗi khách hàng tham gia dự án thay vì sử dụng mặc định.

Bây giờ đối với một số trường hợp đặc biệt của các tệp (ví dụ *.bat *.sh) mà bạn muốn chúng được kiểm tra bằng LF hoặc với CRLF, bạn có thể sử dụng.gitattributes

Tóm lại cho tôi cách thực hành tốt nhất là:

  • Đảm bảo rằng mọi tệp không nhị phân được cam kết với LF trên git repo (hành vi mặc định).
  • Sử dụng lệnh này để đảm bảo rằng không có tập tin được cam kết với CRLF: git grep -I --files-with-matches --perl-regexp '\r' HEAD( Lưu ý: trên cửa sổ khách hàng chỉ hoạt động thông qua git-bashvà về khách hàng linux chỉ khi biên soạn sử dụng --with-libpcretrong ./configure).
  • Nếu bạn tìm thấy bất kỳ tệp nào như vậy bằng cách thực hiện lệnh trên, hãy sửa chúng. Điều này liên quan (ít nhất là trên linux):
    • thiết lập core.autocrlf=input( --- cập nhật 3 - )
    • thay đổi tập tin
    • hoàn nguyên thay đổi (tập tin vẫn được hiển thị là đã thay đổi)
    • cam kết nó
  • Chỉ sử dụng mức tối thiểu .gitattributes
  • Hướng dẫn người dùng đặt các core.autocrlfmô tả ở trên về các giá trị mặc định của nó.
  • Không được tính 100% vào sự hiện diện của .gitattributes. git-client của IDE có thể bỏ qua chúng hoặc đối xử với chúng khác nhau.

Như đã nói một số điều có thể được thêm vào trong các thuộc tính git:

# Always checkout with LF
*.sh            text eol=lf
# Always checkout with CRLF
*.bat           text eol=crlf

Tôi nghĩ rằng một số tùy chọn an toàn khác .gitattributesthay vì sử dụng tự động phát hiện cho các tệp nhị phân:

  • -text(ví dụ: cho *.ziphoặc *.jpgtệp: Sẽ không được coi là văn bản. Do đó, sẽ không có chuyển đổi kết thúc dòng nào được thực hiện. Có thể có thể khác nhau thông qua các chương trình chuyển đổi)
  • text !eol(ví dụ như cho *.java, *.html:.. Bị đối xử như văn bản, nhưng sở thích phong cách eol không được thiết lập Vì vậy, thiết lập khách hàng được sử dụng)
  • -text -diff -merge(ví dụ *.hugefile: Không được coi là văn bản. Không thể tìm khác biệt / hợp nhất)

--- CẬP NHẬT TRƯỚC ---

Một ví dụ đau lòng về một khách hàng sẽ cam kết các tệp sai:

netbeans 8.2 (trên windows), sẽ cam kết sai tất cả các tệp văn bản với CRLF, trừ khi bạn đã đặt rõ ràng core.autocrlflà toàn cục . Điều này mâu thuẫn với hành vi của khách hàng git tiêu chuẩn và gây ra nhiều vấn đề sau này, trong khi cập nhật / hợp nhất. Đây là những gì làm cho một số tệp xuất hiện khác nhau (mặc dù chúng không) ngay cả khi bạn hoàn nguyên .
Hành vi tương tự trong netbeans xảy ra ngay cả khi bạn đã thêm chính xác .gitattributesvào dự án của mình.

Sử dụng lệnh sau sau khi xác nhận, ít nhất sẽ giúp bạn phát hiện sớm xem liệu git repo của bạn có vấn đề kết thúc dòng hay không: git grep -I --files-with-matches --perl-regexp '\r' HEAD

Tôi đã dành hàng giờ để đưa ra cách sử dụng tốt nhất có thể .gitattributes, cuối cùng nhận ra rằng tôi không thể tin vào điều đó.
Thật không may, miễn là các trình soạn thảo dựa trên JGit tồn tại (không thể xử lý .gitattributeschính xác), giải pháp an toàn là buộc LF ở mọi nơi ngay cả ở cấp độ biên tập viên.

Sử dụng các anti-CRLFchất khử trùng sau đây .


Tôi đồng ý với bạn rằng đây là cách tiếp cận tốt nhất, không ai nên sử dụng các biên tập viên mà không có sự hỗ trợ của LF. Nhưng hãy cẩn thận với .gitattributesdòng của bạn , nó có những hậu quả không lường trước trong Git <2.10, xem stackoverflow.com/a/29508751/2261442
phk

Chết tiệt ... Tôi có vô số câu trả lời của tôi ủng hộ git config --global core.autocrlf false, và đề nghị chỉ giải quyết với eol trong các .gitattributeschỉ thị.
VonC

5

Đây chỉ là một giải pháp khắc phục :

Trong trường hợp bình thường, sử dụng các giải pháp được vận chuyển bằng git. Những công việc tuyệt vời trong hầu hết các trường hợp. Buộc phải làm điều đó nếu bạn chia sẻ sự phát triển trên các hệ thống dựa trên Windows và Unix bằng cách đặt .gitattribut .

Trong trường hợp của tôi, có> 10 lập trình viên đang phát triển một dự án trong Windows. Dự án này đã được đăng ký bằng CRLF và không có tùy chọn nào để buộc vào LF.

Một số cài đặt được ghi nội bộ trên máy của tôi mà không có bất kỳ ảnh hưởng nào đến định dạng LF; do đó, một số tệp đã được thay đổi toàn cầu thành LF trên mỗi thay đổi tệp nhỏ.

Giải pháp của tôi:

Windows-Machines: Hãy để mọi thứ như nó vốn có. Không quan tâm đến điều gì, vì bạn là nhà phát triển mặc định 'sói đơn độc' và bạn phải xử lý như thế này: "Không có hệ thống nào khác trên thế giới rộng lớn phải không?"

Máy Unix

  1. Thêm các dòng sau vào phần cấu hình [alias]. Lệnh này liệt kê tất cả các tệp đã thay đổi (tức là đã sửa đổi / mới):

    lc = "!f() { git status --porcelain \
                 | egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \
                 | cut -c 4- ; }; f "
  2. Chuyển đổi tất cả các tệp đã thay đổi thành định dạng dos:

    unix2dos $(git lc)
  3. Tùy chọn ...

    1. Tạo một git hook cho hành động này để tự động hóa quá trình này

    2. Sử dụng thông số và bao gồm nó và sửa đổi grepchức năng để chỉ khớp với tên tệp cụ thể, ví dụ:

      ... | egrep -r "^(\?| ).*\.(txt|conf)" | ...
    3. Hãy làm cho nó thuận tiện hơn nữa bằng cách sử dụng một phím tắt bổ sung:

      c2dos = "!f() { unix2dos $(git lc) ; }; f "

      ... và kích hoạt công cụ chuyển đổi bằng cách gõ

      git c2dos
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.