Tắt chuyển đổi git EOL


100

Tôi đang cố lấy git để không thay đổi bất kỳ kết thúc dòng nào cho bất kỳ hoạt động nào. Thật không may, nó dường như làm như vậy không có vấn đề gì. Tôi đã giảm nó xuống trường hợp thử nghiệm sau, có nhiều cơ chế khác nhau để vô hiệu hóa hành vi này mà tôi có thể tìm thấy.


  • Bắt đầu với hai máy (máy tính Windows = A, máy tính Linux = B)
  • Trên cả hai máy: git config --global core.autocrlf false
  • Trên cả hai máy: git config --global core.eol crlf(chỉ trong trường hợp)

  • Tạo kho lưu trữ mới trên A. Từ một thư mục trống:
    • git init --shared(sau đó bỏ ẩn .gitthư mục đã tạo )
    • Tạo một tệp mới .gitignoretrong kho lưu trữ
    • Tạo một tệp mới .gitattributestrong kho lưu trữ với một dòng:* -text
    • git add ., sau đó git commit -m "initial commit"để làm việc xung quanh, ví dụ như điều này .
    • git branch master_recv
    • Thêm điều khiển từ xa
  • Tạo một tệp mới document.txttrong kho chứa CRLF
  • Cam kết:, git add -Asau đógit commit -m "<something>"
  • Lưu ý rằng A document.txtvẫn chứa CRLF (và xóa nó và đặt lại với --hardtrả về phiên bản vẫn có CRLF)

  • SCP toàn bộ thư mục vào máy tính B
  • Thêm tệp mới new filechứa CRLF
  • Cam kết:, git add -Asau đógit commit -m "<something>"
  • Lưu ý rằng B's document.txtvà B's new fileđều vẫn chứa CRLF

  • Kéo chủ nhân của B đến A: git pull <remote> master:master_recv
  • A document.txtđã thay đổi thành LF. Tệp được thêm vào new filecũng chứa LF.

Sự cố không xảy ra nếu B là máy Windows.


Đã core.autocrlf luôn luôn được sai? Có vẻ như bạn đã có \nkết thúc dòng trong kho lưu trữ của mình? Không cài đặt nào để thay đổi \ntrong kho lưu trữ của bạn thành \r\ntrong thư mục làm việc của bạn.
Edward Thomson

Nó không phải lúc nào cũng được đặt (ví dụ: khi repo được tạo ban đầu). Tuy nhiên, không nên có bất kỳ kết thúc dòng CR nào trong repo. Ngoài ra, một lần nữa, tôi không muốn bất kỳ thay đổi nào xảy ra.
imallett

Tôi yêu cầu vì thiết lập của bạn nên giữ lại phần cuối dòng của bạn là CRLF. Bạn có thể đăng một số tệp trong kho lưu trữ của mình với ID đối tượng của nó chỉ để chỉnh sửa (phải thừa nhận là có thể gây phiền nhiễu) của tôi không?
Edward Thomson

@EdwardThomson ý bạn như thế nào? Repo không công khai (vì máy Linux không). Tôi giả sử bạn muốn một tệp ví dụ. Xem chỉnh sửa.
imallett,

Đúng, tôi đồng ý rằng tệp đó có đuôi dòng CRLF. Bạn có thể làm rõ một điều: bạn đã đề cập rằng "dòng mới của máy tính windows thay đổi thành CR!" Chắc chắn đó là lỗi đánh máy hoặc bạn thực sự nhận được kết thúc dòng trả về kiểu 9 kiểu Mac OS?
Edward Thomson

Câu trả lời:


74

Bên trong dự án của bạn, nên có một .gitattributestệp. Hầu hết thời gian, nó sẽ giống như dưới đây (hoặc ảnh chụp màn hình này ):

# Handle line endings automatically for files detected as text 
# and leave all files detected as binary untouched.
* text=auto

# Never modify line endings of our bash scripts
*.sh -crlf

#
# The above will handle all files NOT found below
#
# These files are text and should be normalized (Convert crlf => lf)
*.css           text
*.html          text
*.java          text
*.js            text
*.json          text
*.properties    text
*.txt           text
*.xml           text

# These files are binary and should be left untouched
# (binary is macro for -text -diff)
*.class         binary
*.jar           binary
*.gif           binary
*.jpg           binary
*.png           binary

Thay đổi * text=autođể * text=falsetắt xử lý tự động (xem ảnh chụp màn hình ).

Như thế này:

nhập mô tả hình ảnh ở đây

Nếu dự án của bạn không có tệp .gitattributes, thì phần cuối của dòng được đặt bởi cấu hình git của bạn. Để thay đổi cấu hình git của bạn, hãy làm như sau:

Đi tới tệp cấu hình trong thư mục này:

1) C: \ ProgramData \ Git \ config

2) Mở tệp cấu hình trong Notepad ++ (hoặc bất kỳ trình soạn thảo văn bản nào bạn thích)

3) Thay đổi "autocrlf =" thành false.

nhập mô tả hình ảnh ở đây


31
Tại sao sử dụng hình ảnh thay vì thẻ mã? Rất bất tiện
Clint

31
Bởi vì tôi có thể thêm một hộp lớn màu đỏ trong hình để làm nổi bật các thứ.
Gene

21
Sử dụng * text=falsekhông hủy đặt văn bản: nó để văn bản được đặt thành giá trị chuỗi sai. Điều này có tác dụng tương tự như để văn bản không xác định (không phải là không đặt cụ thể). Việc sử dụng * -textmang lại cho nó cài đặt chưa đặt đặc biệt. Việc bỏ đặt thuộc tính văn bản trên một đường dẫn cho biết git không cố gắng thực hiện bất kỳ chuyển đổi cuối dòng nào khi đăng ký hoặc thanh toán.
JustAMartin

Cảm ơn bạn @Gene về câu trả lời này. Điều này đã khiến tôi phát điên cả ngày, và điều này đã giải quyết nó cho tôi!
LeopardSkinPillBoxHat

7
Xin lỗi phải nói rằng tôi không thể nói cảm ơn vì câu trả lời này. Tôi mất nửa ngày để biết rằng ai đó đã nghe theo lời khuyên sai lầm. Như @JustAMartin đã chỉ ra * text=falsekhông có tác dụng. Xin hãy sửa câu trả lời!
Paul B.

47

Một giải pháp đơn giản là:

  • đảm bảo rằng core.autocrlf được đặt thành false cho tất cả các repo:
    git config --global core.autocrlf false
  • sao chép lại repo của bạn và kiểm tra xem không có chuyển đổi EOL nào được thực hiện.
  • hoặc, kể từ Git 2.16 (Q1 2018) , hãy giữ repo hiện tại của bạn và thực hiệngit add --renormalize .

Nếu có các chuyển đổi được thực hiện tự động, điều đó có nghĩa là có một .gitattributes core.eolchỉ thị trong repo.

Với Git 2.8+ (tháng 3 năm 2016) , hãy kiểm tra xem có còn chuyển đổi eol hay không với:

git ls-files --eol

2
CHỈ KHÔNG DÙNG autocrlfNGAY HÔM NAY! unsetted autocrlftương đương với false. Bạn tụt lại phía sau các phong trào hợp thời trang trong Git
Lazy Badger

1
Như ở trên, tôi đã thử điều này (mặc dù không phải với cờ toàn cầu) và nó không hoạt động. phiên bản git là 1.8.5.2.
imallett

@IanMallett "Tại thời điểm này, có vẻ như máy Linux vẫn còn CRLF": nó sẽ xảy ra cho đến khi bạn chuẩn hóa lại nội dung của nó hoặc sao chép nó (giống như bạn đã làm trên windows)
VonC

11

Tôi đã hiểu rồi. Có vẻ như chương trình SCP đang chuyển đổi phần cuối của dòng. Tôi nhận thấy điều này khi tôi cố tình tạo tệp có đuôi LF và sau đó quan sát thấy tệp đó xuất hiện dưới dạng CRLF khi tải xuống.

Vì đây là giải pháp cho tôi, tôi chấp nhận câu trả lời này, nhưng những người trong tương lai cũng nên tham khảo các câu trả lời khác để có giải pháp tổng quát hơn.


1
Nắm bắt tốt, cụ thể hơn câu trả lời của tôi. +1
VonC

4

Từ gitattributes (5) Chủ đề "Hiệu ứng" của Trang Thủ công

text

Thuộc tính này cho phép và kiểm soát quá trình chuẩn hóa cuối dòng. Khi một tệp văn bản được chuẩn hóa, phần cuối dòng của nó được chuyển đổi thành LF trong kho lưu trữ. Để kiểm soát kiểu kết thúc dòng nào được sử dụng trong thư mục làm việc, hãy sử dụng eolthuộc tính cho một tệp và core.eol biến cấu hình cho tất cả các tệp văn bản.

Set

Đặt thuộc tính văn bản trên đường dẫn cho phép chuẩn hóa cuối dòng và đánh dấu đường dẫn dưới dạng tệp văn bản. Chuyển đổi cuối dòng diễn ra mà không cần đoán loại nội dung.

Unset Việc bỏ đặt thuộc tính văn bản trên đường dẫn cho phép Git không cố gắng chuyển đổi cuối dòng khi đăng ký hoặc thanh toán.

core.autocrlftrong phiên bản mới (1.7.2+) Git không được sử dụng core.eolvà cài đặt chính xác | hủy đặt thuộc tính văn bản được coi là cách đáng tin cậy hơn


Trong .gitattributestệp, tôi đã tắt rõ ràng mọi thứ dưới dạng văn bản, phải không? Ngoài ra, tôi không thấy nó có tùy chọn để làm cho nó không thực hiện chuyển đổi (mặc dù crlfcó thể không có tác dụng)?
imallett

6
Điều quan trọng thường bị nhầm lẫn - để bỏ đặt textvà ngăn chặn bất kỳ chuyển đổi nào, bạn nên đặt .gitattributes thành * -text và không * text=false. falsekhông phải là giá trị hợp lệ cho textthuộc tính - git sẽ không nhận ra nó và thay vào đó sẽ quay trở lại cài đặt autocrlf mặc định. Ngoài ra, sau khi thay đổi textgiá trị, bạn phải sao lưu tất cả các tệp từ kho lưu trữ cục bộ của mình, thực hiện cam kết, sau đó khôi phục các tệp với phần cuối dòng chính xác khi bạn cần và cam kết lại. Sau đó, phần cuối dòng của bạn sẽ không bị git sửa đổi nữa.
JustAMartin
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.