ฉันจะบังคับให้ git ใช้ LF แทน CR + LF ใน windows ได้อย่างไร


335

ฉันต้องการที่จะบังคับให้คอมไพล์ไปยังไฟล์ที่เช็คเอาท์ภายใต้ Windows โดยใช้เพียงไม่LF CR+LFฉันตรวจสอบสองตัวเลือกการกำหนดค่า แต่ไม่พบการตั้งค่าที่ถูกต้อง

ฉันต้องการแปลงไฟล์ทั้งหมดเป็นLFและเก็บไว้LFในไฟล์

หมายเหตุ: ฉันใช้autocrlf = inputแต่จะเป็นการซ่อมแซมไฟล์เมื่อคุณยืนยัน LFฉันต้องการที่จะบังคับให้พวกเขาได้รับใช้

ฉันอาจไม่ชัดเจนดังนั้น: พื้นที่เก็บข้อมูลที่มีอยู่แล้วโดยใช้LFแต่ไฟล์การตรวจสอบออกมาใช้ msysgit ใช้CR+LFและฉันต้องการที่จะบังคับให้ msysgit ที่จะได้รับพวกเขาด้วยLF: บังคับ Unix ปลายสาย

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

2
autocrlf=inputเป็นตัวเลือกที่ถูกต้อง แน่นอนว่ามันไม่ได้ปกป้องคุณจากไฟล์ที่มีอยู่จริงcr+lfในที่เก็บหรือสร้างไฟล์ด้วยcr+lfในเครื่องมืออื่นก่อนที่จะเพิ่มลงในคอมไพล์ คุณมีปัญหาอะไรที่สิ่งนี้ไม่ได้ผล?
CB Bailey

2
ไฟล์ในที่เก็บนั้นมีการใช้งานแล้วเท่านั้นLFแต่เมื่อฉันได้รับไฟล์เหล่านี้ภายใต้ Windows msysgit จะแปลงไฟล์ให้CR+LFเป็น
sorin

จะต้องมีบางสิ่งบางอย่างในการกำหนดค่าของคุณ; ฉันเพิ่งทดสอบสิ่งนี้ในการติดตั้ง msysgit ของฉัน เมื่อautocrlfตั้งค่าเป็นinputgit จะปล่อยให้lfฟีดบรรทัดเพียงอย่างเดียว คุณสามารถโพสต์การส่งออกของgit config?
CB Bailey

1
ในกรณีนี้ฉันขอแนะนำให้คุณบันทึกข้อบกพร่อง ควรชี้ไปที่ที่เก็บการทดสอบที่แสดงปัญหาของคุณและรวมถึงขั้นตอนในการทำซ้ำเนื่องจากพฤติกรรมที่คุณเห็นนั้นผิดอย่างแน่นอน (แต่ฉันไม่สามารถทำซ้ำได้)
CB Bailey

1
เคล็ดลับเล็ก ๆ คือให้แน่ใจว่าคุณใช้คำสั่ง git บน 'git' ที่คุณคิดว่าคุณเป็น ตัวอย่างเช่นคุณอาจติดตั้งคอมไพล์บน windows และติดตั้งคอมไพล์บน cygwin ดังนั้นตรวจสอบให้แน่ใจว่าคุณได้ตั้งค่า git ที่ถูกต้องแล้ว
lfred

คำตอบ:


106

OP เพิ่มในคำถามของเขา:

ไฟล์ที่เช็คเอาต์โดยใช้ msysgit กำลังใช้งานอยู่CR+LFและฉันต้องการบังคับให้ msysgit ทำการติดตั้งLF

ขั้นตอนแรกง่ายๆยังคงอยู่ใน.gitattributesไฟล์:

# 2010
*.txt -crlf

# 2020
*.txt text eol=lf 

(ตามที่ระบุไว้ในการแสดงความคิดเห็นโดยหลานหมายถึงการ.gitattributesสิ้นสุดของบรรทัดแปลง ) เพื่อหลีกเลี่ยงการแปลงไฟล์ที่ถูกต้องด้วยCRLFeol

และผมได้แนะนำเสมอ git config --global core.autocrlf falseที่จะปิดการใช้งานการแปลงใด ๆ (ซึ่งจะนำไปใช้กับทุกไฟล์ versioned)

ดูแนวทางปฏิบัติที่ดีที่สุดสำหรับการตั้งค่า git ข้ามแพลตฟอร์ม?

ตั้งแต่ Git 2.16 (Q1 2018) คุณสามารถใช้git add --renormalize .เพื่อใช้.gitattributesการตั้งค่าเหล่านั้นได้ทันที


แต่ขั้นตอนที่สองที่มีประสิทธิภาพยิ่งขึ้นนั้นเกี่ยวข้องกับไดร์เวอร์ตัวกรอง gitattributeและเพิ่มขั้นตอนรอยเปื้อน

ฟิลเตอร์ไดรเวอร์

เมื่อใดก็ตามที่คุณจะอัปเดตแผนผังการทำงานของคุณสคริปต์สามารถทำได้เฉพาะไฟล์ที่คุณระบุในตัวเลือก.gitattributesบังคับLF eolและตัวเลือกการจัดรูปแบบอื่น ๆ ที่คุณต้องการบังคับใช้
หากclearสคริปต์ "" ไม่ได้ทำอะไรเลยคุณจะแปลงไฟล์ของคุณ (หลังจากคอมมิชชัน) โดยใช้รูปแบบที่คุณต้องการให้ติดตาม


คำถามหนึ่งข้อ: * .txt หมายถึงไฟล์ทั้งหมดที่มีนามสกุล. txt หรือไฟล์ข้อความทั้งหมด (ไม่ใช่ไบนารี) ฉันไม่สามารถสร้างรายการที่มีนามสกุลไฟล์ทุกชนิดที่ฉันจะมีในโครงการ
sorin

1
@Sorin: ไฟล์ทั้งหมดที่มี.txtนามสกุล คุณควรเริ่มสร้างสิ่งนี้ก่อนและทดสอบกับกลุ่มที่เฉพาะเจาะจงก่อนที่จะสรุปเป็น * และเพิ่มกฎเชิงลบ!*.xyz ...เพื่อแยกไฟล์บางไฟล์ออกจากกฎนั้น
VonC

1
โดยตอนนี้.gitattributesบรรทัดควรอ่าน: *.txt text eol=lfตามgit-scm.com/docs/gitattributes
หลาน

@grandchild ขอบคุณ ฉันได้รวมความคิดเห็นของคุณไว้ในคำตอบเพื่อให้มองเห็นได้ชัดเจนขึ้น
VonC

ฉันเดาว่าหลังจากที่เราเพิ่ม.gitattributesเราต้องทำgit add --renormalize .
shuva

461

วิธีที่เหมาะสมในการรับ LF ตอนจบใน Windows คือการตั้งค่าcore.autocrlfเป็นfalse:

git config --global core.autocrlf false

คุณต้องทำสิ่งนี้ถ้าคุณใช้ msysgit เพราะมันตั้งไว้trueในการตั้งค่าระบบ

ตอนนี้คอมไพล์จะไม่ทำการฟื้นฟูบรรทัดที่สิ้นสุด หากคุณต้องการให้ไฟล์ที่คุณเช็คอินเป็นมาตรฐานให้ทำดังนี้: ตั้งค่าtext=autoใน.gitattributesไฟล์ทั้งหมดของคุณ:

* text=auto

และตั้งcore.eolเป็นlf:

git config --global core.eol lf

ตอนนี้คุณยังสามารถสลับ repos เดียวเป็น crlf (ในไดเรกทอรีการทำงาน!) โดยการเรียกใช้

git config core.eol crlf

หลังจากที่คุณได้กระทำการกำหนดค่าคุณอาจต้องการที่จะคอมไพล์ปกติไฟล์ทั้งหมดในrepo เมื่อต้องการทำสิ่งนี้ให้ไปที่รูทของ repo ของคุณและรันคำสั่งเหล่านี้:

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

หากคุณต้องการให้คอมไพล์ปรับมาตรฐานไฟล์ในไดเร็กทอรีการทำงานของคุณให้รันคำสั่งเหล่านี้:

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

3
ฉันได้รับ pathspec ที่ร้ายแรง '' ไม่ตรงกับไฟล์ใด ๆ หลังจากgit diff --cached --name-only -z | xargs -0 git add
CMCDragonkai

3
ผลลัพธ์ของgit diff --cached --name-onlyอะไร
Chronial

1
มันอาจจะเป็นมูลค่าการกล่าวขวัญว่าคุณสามารถตั้งค่าการกำหนดค่านี้ในขณะที่โคลน repo git clone --config core.autocrlf=false <repo path>ในคำถามเช่น
Chris Long

240

ฉันกลับมาที่คำตอบนี้บ่อยครั้งแม้ว่าจะไม่มีสิ่งใดที่เหมาะสมสำหรับฉัน ที่กล่าวว่าคำตอบที่เหมาะสมสำหรับฉันคือการผสมผสานของคนอื่น ๆ

สิ่งที่ฉันพบคืองานต่อไปนี้:

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

สำหรับ repos ที่เช็คเอาต์หลังจากการตั้งค่าส่วนกลางเหล่านั้นทุกอย่างจะถูกตรวจสอบว่าเป็นสิ่งที่อยู่ใน repo - หวังว่าLF( \n) ใด ๆCRLFจะถูกแปลงเป็นเพียงLFการเช็คอิน

ด้วย repo ที่มีอยู่ซึ่งคุณได้ตรวจสอบแล้ว - ที่มีการลงท้ายบรรทัดที่ถูกต้องใน repo แต่ไม่ใช่สำเนาการทำงานของคุณ - คุณสามารถเรียกใช้คำสั่งต่อไปนี้เพื่อแก้ไข:

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

การดำเนินการนี้จะลบ ( rm) ซ้ำ ( r) โดยไม่แจ้ง ( -f) ไฟล์ทั้งหมดยกเว้นไฟล์ที่คุณแก้ไข ( --cached) จากไดเรกทอรีปัจจุบัน ( .) resetแล้วส่งกลับทั้งหมดของไฟล์เหล่านั้นไปยังรัฐที่พวกเขามีตอนจบที่แท้จริงของพวกเขาบรรทัด (ที่ตรงกับสิ่งที่อยู่ในซื้อคืนบริการ)

หากคุณต้องการแก้ไขจุดสิ้นสุดของไฟล์ใน repo ฉันขอแนะนำให้คุณใช้โปรแกรมแก้ไขที่จะช่วยให้คุณทำเช่นนั้นได้เช่น IntelliJ หรือ Sublime Text แต่ฉันแน่ใจว่ามีสิ่งที่ดีพอที่จะสนับสนุนสิ่งนี้


1
เรามี repo ที่มีไดเรกทอรีย่อยที่ต้องการการจัดการการสิ้นสุดบรรทัดที่แตกต่างกัน ดังนั้นการตั้งค่าตัวเลือกสากลจะไม่ทำงานสำหรับสิ่งนี้ ไม่แม้แต่ใน repo เดียว คุณใช้การตั้งค่าเดียวกันนี้ใน. gitattributes อย่างไร
RobG

Notepad++ยังแสดงให้เห็นถึงการสิ้นสุดบรรทัดของไฟล์ที่เปิดอยู่ที่มุมขวาล่าง การคลิกขวาบนฟิลด์นั้นจะช่วยให้คุณเปลี่ยนการสิ้นสุดบรรทัด
winklerrr

1
core.autocrlf inputตัวเลือกแทนที่การcore.eolตั้งค่าเพื่อให้การตั้งค่าทั้งซ้ำซ้อน (ดูgit-scm.com/docs/git-config )
Andrew Marshall

1
ขอบคุณด้วยความช่วยเหลือของคุณฉันได้ยึดผ้าสำลีและ Linux และตอนนี้สามารถเช็คอินไฟล์
GC_

57

บริบท

ถ้าคุณ

  1. ต้องการบังคับให้ผู้ใช้ทุกคนมีจุดสิ้นสุดบรรทัด LF สำหรับไฟล์ข้อความและ
  2. คุณไม่สามารถมั่นใจได้ว่าผู้ใช้ทุกคนเปลี่ยนการตั้งค่า git ของพวกเขา

คุณสามารถทำได้โดยเริ่มจาก git 2.10 2.10 หรือสูงกว่าเป็นสิ่งจำเป็นเพราะ2.10 การแก้ไขพฤติกรรมของข้อความ = อัตโนมัติร่วมกับ EOL แหล่ง

สารละลาย

วาง.gitattributesไฟล์ในรูทของที่เก็บ git ของคุณมีเนื้อหาดังต่อไปนี้:

* text=auto eol=lf

กระทำมัน

ปรับแต่งเสริม

คุณยังสามารถเพิ่ม.editorconfigในรูทของที่เก็บของคุณเพื่อให้แน่ใจว่าการใช้เครื่องมือที่ทันสมัยสร้างไฟล์ใหม่ด้วยการสิ้นสุดบรรทัดที่ต้องการ

# 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
นี่เป็นทางออกที่ดีที่สุดสำหรับฉัน ฉันรวมสิ่งนี้กับeditorconfig.orgเพื่อที่เมื่อเขียนใน Intellij ฉันจะเขียน LF EOLs
Jazzepi

นี่คือทางออกที่ดีที่สุด ไม่จำเป็นต้องเรียกใช้คำสั่งกำหนดค่าใด ๆ !
Cameron Tacklind

26

core.autocrlf=inputเป็นการตั้งค่าที่เหมาะสมสำหรับสิ่งที่คุณต้องการ แต่คุณอาจต้องทำgit update-index --refreshและ / หรือ a git reset --hardเพื่อให้การเปลี่ยนแปลงมีผล

เมื่อcore.autocrlfตั้งค่าเป็นinputgit จะไม่ใช้การแปลงบรรทัดใหม่ในการเช็คเอาท์ (ดังนั้นหากคุณมี LF ใน repo คุณจะได้รับ LF) แต่จะทำให้แน่ใจว่าในกรณีที่คุณเลอะและแนะนำ CRLF บางอย่างในการทำงาน พวกเขาจะไม่เดินเข้าไปใน repo


19
คำสั่งควรเป็น git rm --cached -r && git reset
ฮาร์ด

0

คุณสามารถค้นหาวิธีแก้ไขปัญหานี้ได้ที่: https://help.github.com/th/github/using-git/configuring-git-to-handle-line-endings

คำอธิบายที่ง่ายขึ้นเกี่ยวกับวิธีที่คุณสามารถแก้ไขปัญหานี้ได้บน windows:

การตั้งค่าส่วนกลางสำหรับการสิ้นสุดบรรทัดคำสั่ง git config core.autocrlf ใช้เพื่อเปลี่ยนวิธีที่ Git จัดการการสิ้นสุดบรรทัด ใช้อาร์กิวเมนต์เดียว

บน Windows คุณเพียงแค่ส่งผ่านค่าจริง ตัวอย่างเช่น: C:> git config --global core.autocrlf จริง

โชคดีฉันหวังว่าฉันช่วย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.