ทำไมฉันถึงควรใช้ core.autocrlf = true ใน Git


296

ฉันมีที่เก็บ Git ที่สามารถเข้าถึงได้จากทั้ง Windows และ OS X และฉันรู้ว่ามีไฟล์บางไฟล์ที่มี CRLF line-endings เท่าที่ฉันสามารถบอกได้มีสองวิธีในการจัดการกับเรื่องนี้:

  1. ตั้งcore.autocrlfไปfalseทุกที่

  2. ทำตามคำแนะนำที่นี่ (echoed บนหน้าความช่วยเหลือของ GitHub) เพื่อแปลงพื้นที่เก็บข้อมูลให้มีเฉพาะจุดสิ้นสุด LF และหลังจากนั้นตั้งcore.autocrlfเป็นtrueWindows และinputOS X ปัญหาในการทำเช่นนี้คือถ้าฉันมีไฟล์ไบนารีใด ๆ ในที่เก็บ ที่:

    1. ทำเครื่องหมายไม่ถูกต้องว่าเป็นไบนารีใน gitattributes และ
    2. มีทั้ง CRLF และ LF

    พวกเขาจะเสียหาย เป็นไปได้ว่าที่เก็บของฉันมีไฟล์ดังกล่าว

เหตุใดฉันจึงไม่ควรปิดการแปลงตอนจบของ Git มีคำเตือนที่คลุมเครือบนเว็บจำนวนมากเกี่ยวกับการcore.autocrlfปิดสวิตช์ที่ก่อให้เกิดปัญหา แต่มีน้อยมากโดยเฉพาะคน; สิ่งเดียวที่ฉันได้พบจนถึงขณะนี้คือ kdiff3 ไม่สามารถจัดการกับตอนจบ CRLF (ไม่ใช่ปัญหาสำหรับฉัน) และตัวแก้ไขข้อความบางรายการมีปัญหาในการสิ้นสุดบรรทัด (เช่นกันไม่ใช่ปัญหาสำหรับฉัน)

ที่เก็บอยู่ภายใน บริษัท ของฉันดังนั้นฉันไม่ต้องกังวลเกี่ยวกับการแบ่งปันกับผู้ที่มีการตั้งค่า autocrlf หรือข้อกำหนดการสิ้นสุดบรรทัดต่าง ๆ

มีปัญหาอื่นอีกหรือไม่ที่เพิ่งออกจากสายงานตอนจบตามที่ฉันไม่รู้?


1
จะstackoverflow.com/questions/2333424/...ความช่วยเหลือ? ฉันมีลิงก์ไปยังสาเหตุที่เฉพาะเจาะจงสำหรับการปล่อยautocrlfให้เป็นเท็จ
VonC

3
@VonC ขอบคุณ แต่ฉันสามารถบอกได้ว่าผู้ใช้ทุกคนใน บริษัท ได้ตั้งค่า <code> autocrlf </code> เป็นเท็จและในขณะนี้เชื่อว่าเป็นตัวเลือกที่ดีที่สุด แต่ฉันต้องการทราบว่ามีสาเหตุใดบ้างที่ฉันไม่ควรทำอย่างนั้นเพราะฉันพบว่ามีคนจำนวนมาก (เช่น GitHub) ที่บอกว่าฉันควรตั้งค่าautocrlf แต่ไม่มีลักษณะเฉพาะที่แท้จริงว่าทำไม
รวย

3
@VonC เช่นฉันไม่ได้มองหาเหตุผลที่จะตั้งค่าautocrlfเป็นเท็จ ฉันกำลังมองหาสาเหตุที่ทำให้มันเป็นจริง
รวย

9
ทำไมไม่ใช้autocrlf = input: มันดูเหมือนจะเป็นความละเอียดที่สมบูรณ์แบบระหว่างสองขั้ว: คุณรักษา repo ของคุณจาก CRLF crap และนักพัฒนา Windows ในพื้นที่สามารถใช้สิ่งที่พวกเขาต้องการโดยไม่ต้องใช้ไฟล์ภายในเครื่อง (พวกเขาอาจต้องการ LF ในประเทศด้วยเหตุผลต่างๆดังนั้นtrueจะไม่ดีในความคิดของฉัน.) ฉันไม่สามารถเห็นข้อเสียใด ๆ autocrlf = inputที่จะใช้
iconoclast

7
@iconclast เหตุผลหนึ่งที่ฉันพบคือถ้าคุณสร้างดิสทริบิวชันที่มีทั้งแบตช์ไฟล์ Windows และสคริปต์เชลล์ Unix คุณต้องการใช้บรรทัดที่ถูกต้องซึ่งลงท้ายด้วยแต่ละกรณีและการทำเช่นนี้จะทำได้ยากกว่าหาก Git กำลังทำสิ่งรอบตัวแม้หลังจากที่คุณตั้งค่าไว้ไม่ทางใดก็ทางหนึ่ง
user1809090

คำตอบ:


227

เหตุผลเฉพาะที่กำหนดautocrlfให้trueเป็น:

  • หลีกเลี่ยงการgit statusแสดงไฟล์ทั้งหมดของคุณmodifiedเนื่องจากการแปลง EOL อัตโนมัติเสร็จสิ้นเมื่อทำการโคลน repo EOL Git ที่ใช้ Unix บน Windows หนึ่ง (ดูที่ปัญหา 83เป็นต้น)
  • และเครื่องมือการเข้ารหัสของคุณอย่างใดขึ้นอยู่กับพื้นเมืองสไตล์ EOL เป็นอยู่ในปัจจุบันในไฟล์ของคุณ:
    • ตัวอย่างเช่นตัวสร้างโค้ดใช้รหัสในการตรวจจับ EOL ดั้งเดิม
    • ชุดภายนอกอื่น ๆ (ภายนอก repo ของคุณ) ด้วย regexp หรือชุดรหัสเพื่อตรวจหา EOL ดั้งเดิม
    • ฉันเชื่อว่าปลั๊กอิน Eclipse บางอย่างสามารถสร้างไฟล์ด้วย CRLF โดยไม่คำนึงถึงแพลตฟอร์มซึ่งอาจเป็นปัญหาได้
    • คุณใช้รหัสกับ Notepad.exe ( เว้นแต่ว่าคุณกำลังใช้ Windows 10 2018.09+ โดยที่ Notepad ตรวจพบอักขระ EOL )

จนกว่าคุณจะสามารถเห็นการรักษาที่เฉพาะเจาะจงที่จะต้องจัดการกับ EOL พื้นเมืองคุณจะดีกว่าออกautocrlfไปfalse (git config --global core.autocrlf false )

โปรดทราบว่าการกำหนดค่านี้จะเป็นท้องถิ่น (เนื่องจากการกำหนดค่าไม่ได้ถูกส่งจาก repo เป็น repo)

หากคุณต้องการกำหนดค่าเดียวกันสำหรับผู้ใช้ทั้งหมดที่คัดลอก repo นั้นลองดู " กลยุทธ์การจัดการที่ดีที่สุดCRLFกับ git คืออะไร " โดยใช้textแอตทริบิวต์ใน.gitattributesไฟล์ไฟล์

ตัวอย่าง:

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

หมายเหตุ: การเริ่มต้นคอมไพล์ 2.8 (มีนาคม 2559) เครื่องหมายการรวมจะไม่แนะนำการลงท้ายด้วยเส้นผสม (LF) ในไฟล์ CRLF อีกต่อไป
ดูที่ " ทำให้ Git ใช้ CRLF ใน" <<<<<<< HEAD "รวมบรรทัด "


5
@VonC ขอบคุณ! autocrlf=falseที่ช่วยให้ฉันรู้สึกมั่นใจมากขึ้นว่ามันเป็นที่ปลอดภัยสำหรับผมที่จะใช้ คุณรู้หรือไม่ว่าเหตุใด git ยังคงทำการแปลง eol แม้ว่าคุณจะตั้งค่า autocrlf เป็นเท็จหรือไม่
รวย

14
@VonC: ฉันไม่คิดว่าคำตอบนี้ถูกต้อง การใช้ core.autocrlf = true บน Windows ทำงานตามที่คาดไว้ ไฟล์ทั้งหมดจาก repo (ซึ่งควรมีจุดสิ้นสุดบรรทัด LF ในสถานการณ์นี้) จะถูกแปลงเป็นตอนจบบรรทัด CRLF เมื่อชำระเงินเป็นพีซี Windows ไฟล์ทั้งหมดจะถูกแปลงกลับไปเป็นจุดสิ้นสุดบรรทัด LF เมื่อคอมมิชชันจาก Windows PC วิธีที่จะประสบปัญหาคือการเช็คเอาต์ครั้งแรกกับพีซีที่ใช้ Windows ด้วยการตั้งค่า core.autocrlf ที่ไม่ถูกต้อง (ซึ่งทำได้ง่ายเกินไป)
Michael Maddox

3
@Michael ดังนั้นในกรณีนี้มีเหตุผลเดียวที่จะไม่ใช้core.autocrlf=falseในสถานการณ์จำลองของฉันหากฉันมีเครื่องมือ / เครื่องมือแก้ไขที่จะทำให้สับสนโดยการวางสาย
ริช

49
ฉันจะใช้แน่นอนfalseฉันไม่เคยเป็นแฟนตัวยงของสิ่งอัตโนมัติหรือเวทมนตร์ที่เกิดขึ้นในพื้นหลัง เพียงแค่ใช้\nและUTF-8ทุกที่และคุณจะปรับ หากหัวน๊อตบางคนไม่เข้าใจว่ามีการประชุมและกฎระเบียบและลืมที่จะใช้UTF-8หรือ\nมีบางคนแปลงพวกเขาด้วยตนเองและตบหน้าของเขา
หอคอย

5
@ Pauld'Aoust ฉันยังต้องการระบุประเภทของไฟล์ที่ต้องการให้ CRLF ผ่านcore.eolแอตทริบิวต์ใน.gitattributesไฟล์แทนที่จะใช้core.autocrlfการตั้งค่าส่วนกลางนี้ซึ่งใช้กับไฟล์ทั้งหมดโดยไม่เลือกปฏิบัติ
VonC

40

ฉันเป็นผู้พัฒนา. NET และใช้ Git และ Visual Studio มาหลายปี คำแนะนำที่แข็งแกร่งของฉันคือตั้งค่าการจบบรรทัดเป็นจริง และทำมันให้เร็วที่สุดเท่าที่จะทำได้ในช่วงชีวิตของ Repository ของคุณ

ที่ถูกกล่าวว่าฉันเกลียดที่ Git เปลี่ยนจุดสิ้นสุดของฉัน การควบคุมแหล่งที่มาควรบันทึกและดึงงานที่ฉันทำเท่านั้นไม่ควรแก้ไข เคย. แต่มันก็เป็นเช่นนั้น

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


บริษัท ของฉันมีขนาดเล็กพอที่เราสามารถรับรองได้ว่ามีการใช้งานเท็จทุกที่และฉันคิดว่า บริษัท ขนาดใหญ่สามารถทำสิ่งนี้ผ่านนโยบายได้ แต่ฉันคิดว่านี่เป็นเหตุผลที่ถูกต้องสำหรับการใช้ "จริง" ดังนั้นฉันจึง upvoting อย่างไรก็ตาม. ขอบคุณ!
Rich

1
ปัญหาในการทำเช่นนี้กับนโยบาย (บังคับใช้ไฟล์) คือบนเครื่อง windows คุณสามารถมีไฟล์ local, global, และ config ที่ซ่อนอยู่ (ProgramData / Git / Confg) คุณสามารถบังคับใช้โลคัลโดยตรวจสอบลงใน repo แต่ไฟล์ Global และไฟล์ที่ซ่อนจะมีความสำคัญกว่า นอกจากนี้ยังเป็นไปได้ที่จะมีในท้องถิ่นและระดับโลก (หรือซ่อนอยู่) จะแตกต่างกัน หากเป็นเช่นนั้นพวกเขาจะขัดแย้งกันบนเครื่อง SAME ทำให้เกิดข้อผิดพลาดในการสิ้นสุดบรรทัดเมื่อไม่มีเลย นี่เป็นความเจ็บปวดที่ต้องตามหา :(
JGTaylor

7
สิ่งที่ฉันคิด มันไม่ใช่งานของตัวควบคุมแหล่งที่มาที่จะยุ่งกับไฟล์โค้ดตามที่มันต้องการ การสิ้นสุดบรรทัดนั้นควรเป็นเรื่องของเครื่องมือแก้ไขเท่านั้น
Tuncay Göncüoğlu

6
หากโครงการของคุณเป็น Windows เท่านั้นไม่มีปัญหา อย่างไรก็ตามหากคุณหรือเพื่อนร่วมงานของคุณทำงานบนแพลตฟอร์ม * ระวังแล้ว "คำแนะนำที่ดี" ของคุณจะทำให้เกิดปัญหา ลองใช้ bash, perl หรือ python script กับ shebang ลงท้ายด้วย\r\nและคุณจะเห็น
phuclv

6
สถานการณ์ที่คุณอธิบายว่าไม่ใช่ปัญหาของ GIT ตั้งค่าเป็น FALSE ตามที่ควรจะเป็นและหายไป ในกรณีนี้มันเป็นปัญหาในการทำงานเป็นทีม มันหมายความว่าอะไร "ในที่สุดผู้พัฒนาชุดเดียวtrue" ทำไมคุณถึงยอมให้พวกเขารู้ตั้งแต่แรก? เมื่อคุณตั้งค่าเพื่อเข้าถึง repo git เช่นเดียวกับที่คุณไม่อนุญาตให้สร้างมลภาวะในบางพื้นที่ด้วย langs ที่แตกต่างกัน (ดังนั้นทุกคนที่ทำงานในที่สามารถอ่านได้) หรือเหมือนกับที่คุณเก็บสาขา / การรวม / rebases / ฯลฯ ตามที่เลือก นโยบายพวกเขาควรได้รับกฎที่ชัดเจน: ตั้งค่า crlf ที่ถูกต้อง
quetzalcoatl

12

อัปเดต 2 :

Xcode 9 ดูเหมือนจะมี "คุณสมบัติ" ซึ่งจะไม่สนใจการสิ้นสุดบรรทัดปัจจุบันของไฟล์และเพียงแค่ใช้การตั้งค่าการสิ้นสุดบรรทัดเริ่มต้นของคุณเมื่อแทรกบรรทัดลงในไฟล์ทำให้เกิดไฟล์ที่มีจุดสิ้นสุดของเส้นผสม

ฉันค่อนข้างมั่นใจว่าข้อผิดพลาดนี้ไม่มีอยู่ใน Xcode 7 ไม่แน่ใจเกี่ยวกับ Xcode 8 ข่าวดีก็คือว่ามันได้รับการแก้ไขใน Xcode 10

สำหรับเวลาที่มีอยู่ข้อผิดพลาดนี้ทำให้เกิดความฮือฮาเล็กน้อยใน codebase ที่ฉันอ้างถึงในคำถาม (ซึ่งทุกวันนี้ใช้autocrlf=false) และนำไปสู่ข้อความ "EOL" หลายข้อความและในที่สุดฉันก็เขียน git pre-commithook เพื่อตรวจสอบ สำหรับ / ป้องกันการแนะนำการสิ้นสุดของบรรทัดแบบผสม

อัปเดต :

หมายเหตุ: เท่าที่สังเกตจาก VonC เริ่มต้นจาก Git 2.8 เครื่องหมายผสานจะไม่แนะนำ Unix สไตล์สายลงท้ายไฟล์

ต้นฉบับ :

อาการสะอึกเล็กน้อยที่ฉันได้สังเกตเห็นด้วยการตั้งค่านี้คือเมื่อมีการรวมความขัดแย้งบรรทัด git เพิ่มเพื่อทำเครื่องหมายความแตกต่างไม่มีจุดสิ้นสุดบรรทัด Windows แม้เมื่อส่วนที่เหลือของไฟล์ทำและคุณสามารถท้าย กับไฟล์ที่มีจุดสิ้นสุดของบรรทัดแบบผสมเช่น:

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

สิ่งนี้ไม่ได้ทำให้เราเกิดปัญหาใด ๆ (ฉันคิดว่าเครื่องมือใด ๆ ที่สามารถจัดการกับปลายสายทั้งสองประเภทจะจัดการกับปลายสายแบบผสมได้อย่างแน่นอน - ทุกอย่างที่เราใช้ทำ) แต่มันเป็นสิ่งที่ต้องระวัง

สิ่งอื่น ๆ* ที่เราพบคือเมื่อใช้git diffเพื่อดูการเปลี่ยนแปลงไฟล์ที่มีการสิ้นสุดบรรทัด Windows บรรทัดที่ถูกเพิ่มจะแสดงการขึ้นบรรทัดใหม่ดังนั้น:

    // Not changed

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

* มันไม่ได้ทำบุญจริงๆ: "ปัญหา"


2
NB เมื่อ Visual Studio พบไฟล์ดังกล่าวจะเสนอการทำบรรทัดรายการให้คุณตามปกติ การเลือกบรรทัดสิ้นสุดของ Windows หรือการเลือกที่จะไม่ทำให้บรรทัดจบของบรรทัดทำงานปกติ (เนื่องจาก VS ยังแสดงอย่างถูกต้องบรรทัดที่ละเมิดจะถูกลบเมื่อความขัดแย้งได้รับการแก้ไข)
Rich

2
น่าเสียดายที่การควบคุมเวอร์ชันขององค์กร nazis ไม่เห็นด้วยกับมัน (LF เกี่ยวกับการรวมเครื่องหมายความขัดแย้ง) ไม่เป็นปัญหา
Ilia G

1
ฉันยอมรับว่า LF เกี่ยวกับการรวมเครื่องหมายความขัดแย้งไม่ควรเป็นปัญหา บรรทัดเหล่านั้นไม่ควรมุ่งมั่นที่จะซื้อคืนอย่างไรก็ตาม
ปล้น

1
หมายเหตุ: การเริ่มต้นคอมไพล์ 2.8 (มีนาคม 2559) เครื่องหมายรวมจะมีการสิ้นสุดบรรทัด CRLF จริง ดูstackoverflow.com/a/35474954/6309
VonC
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.