Mengapa saya harus menggunakan core.autocrlf = true di Git?

296

Saya memiliki repositori Git yang diakses dari Windows dan OS X, dan yang saya tahu sudah berisi beberapa file dengan akhiran CRLF. Sejauh yang saya tahu, ada dua cara untuk mengatasinya:

  1. Diatur core.autocrlfke falsemana - mana,

  2. Ikuti instruksi di sini (digaungkan di halaman bantuan GitHub) untuk mengonversi repositori menjadi hanya berisi akhir-baris LF, dan setelah itu disetel core.autocrlfke trueWindows dan inputpada OS X. Masalah dengan melakukan ini adalah jika saya memiliki file biner di repositori bahwa:

    1. tidak ditandai dengan benar sebagai biner di gitattributes, dan
    2. kebetulan mengandung CRLF dan LF,

    mereka akan rusak. Mungkin repositori saya berisi file-file seperti itu.

Jadi mengapa saya tidak mematikan saja konversi akhir baris Git? Ada banyak peringatan samar di web tentang core.autocrlfmematikan yang menyebabkan masalah, tetapi sangat sedikit yang spesifik ; satu-satunya yang saya temukan sejauh ini adalah bahwa kdiff3 tidak dapat menangani akhiran CRLF (bukan masalah bagi saya), dan bahwa beberapa editor teks memiliki masalah akhir baris (juga bukan masalah bagi saya).

Repositori adalah internal perusahaan saya, jadi saya tidak perlu khawatir membagikannya dengan orang-orang dengan pengaturan autocrlf yang berbeda atau persyaratan akhir baris.

Apakah ada masalah lain dengan hanya meninggalkan garis akhir karena-saya tidak menyadarinya?

Kaya
sumber
1
Apakah stackoverflow.com/questions/2333424/… membantu? Saya memiliki tautan ke alasan spesifik untuk meninggalkan autocrlfke false.
VonC
3
@VonC Terima kasih, tetapi saya sudah dapat menentukan bahwa semua pengguna di perusahaan menetapkan <code> autocrlf </code> menjadi false dan saat ini percaya bahwa itu menjadi pilihan terbaik. Tapi saya ingin tahu apakah ada alasan mengapa saya tidak boleh melakukan itu, karena saya dapat menemukan ada banyak orang (misalnya GitHub) yang mengatakan saya autocrlf harus ditetapkan tetapi tidak ada spesifik sebenarnya mengapa.
Kaya
3
@VonC yaitu saya tidak mencari alasan untuk disetel autocrlfke false. Saya mencari alasan untuk menjadikannya benar.
Kaya
9
Mengapa tidak menggunakan autocrlf = input: tampaknya ini adalah resolusi sempurna antara kedua ekstrem: Anda menjaga repo Anda bersih dari omong kosong CRLF, dan secara lokal pengembang Windows dapat menggunakan apa pun yang mereka inginkan tanpa file lokal mereka memiliki sihir yang dilakukan secara otomatis kepada mereka. (Mereka mungkin menginginkan LF secara lokal karena berbagai alasan, jadi trueitu buruk, menurut saya.) Saya tidak bisa melihat ada kerugian untuk menggunakan autocrlf = input.
iconoclast
7
@iconclast, salah satu alasan saya bertemu adalah jika Anda membangun distribusi yang menyertakan file batch Windows dan skrip Unix shell. Anda ingin menggunakan baris yang benar yang berakhir pada setiap kasus, dan ini lebih sulit dilakukan jika Git mengelabui hal-hal di sekitar bahkan setelah Anda secara eksplisit mengaturnya.
user1809090

Jawaban:

227

Alasan hanya khusus untuk set autocrlfke trueadalah:

  • hindari git statusmenampilkan semua file Anda modifiedkarena konversi EOL otomatis yang dilakukan ketika mengkloning repo EOL Git berbasis Unix ke yang Windows (lihat masalah 83 misalnya)
  • dan alat pengkodean Anda entah bagaimana tergantung pada gaya EOL asli yang ada di file Anda:

Kecuali Anda dapat melihat perawatan khusus yang harus berurusan dengan EOL asli, Anda lebih baik pergi autocrlfkefalse ( git config --global core.autocrlf false).

Perhatikan bahwa konfigurasi ini akan menjadi konfigurasi lokal (karena konfigurasi tidak didorong dari repo ke repo)

Jika Anda menginginkan konfigurasi yang sama untuk semua pengguna yang mengkloning repo itu, lihat " Apa CRLFstrategi penanganan terbaik dengan git? ", Menggunakan textatribut dalam .gitattributesfile .

Contoh:

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

Catatan: mulai git 2.8 (Maret 2016), marka gabungan tidak akan lagi memperkenalkan akhiran campuran garis (LF) dalam file CRLF.
Lihat " Buat Git menggunakan CRLF pada baris gabungan" <<<<<<< HEAD " "

VONC
sumber
5
@VonC Terima kasih! Itu membantu saya merasa lebih percaya diri bahwa aman untuk saya gunakan autocrlf=false. Karena ketertarikan, apakah Anda tahu mengapa git masih melakukan konversi awal bahkan jika Anda memiliki autoclf yang disetel ke false?
Kaya
14
@VonC: Saya kira jawaban ini tidak benar. Menggunakan core.autocrlf = true pada Windows berfungsi seperti yang diharapkan. Semua file dari repo (yang seharusnya memiliki ujung garis LF dalam skenario ini) dikonversi ke ujung garis CRLF saat checkout ke PC Windows. Semua file dikonversi kembali ke akhir baris LF saat komit dari PC Windows. Cara untuk mendapat masalah adalah untuk checkout awalnya ke PC Windows dengan pengaturan core.autocrlf yang salah (yang sepenuhnya terlalu mudah dilakukan).
Michael Maddox
3
@Michael Jadi dalam hal ini adalah satu-satunya alasan untuk tidak menggunakan core.autocrlf=falsedalam skenario saya adalah jika saya memiliki beberapa alat / editor yang akan bingung dengan akhir baris?
Kaya
49
Saya pasti akan menggunakan false, saya tidak pernah menjadi penggemar berat hal-hal otomatis atau sihir yang terjadi di latar belakang. Cukup gunakan \ndan di UTF-8mana - mana dan Anda akan baik-baik saja. Jika beberapa orang gila tidak mengerti bahwa ada konvensi dan aturan dan lupa untuk menggunakan UTF-8atau \n, maka seseorang mengubahnya secara manual dan menampar wajahnya.
Menara
5
@ Pauld'Aoust Saya masih lebih suka untuk menentukan jenis file yang membutuhkan CRLF melalui core.eolatribut dalam .gitattributesfile, daripada menggunakan core.autocrlfpengaturan global ini yang berlaku tanpa pandang bulu untuk semua file.
VonC
40

Saya seorang pengembang .NET, dan telah menggunakan Git dan Visual Studio selama bertahun-tahun. Rekomendasi saya yang kuat adalah mengatur akhir baris menjadi true. Dan lakukan sedini mungkin dalam masa penyimpanan Anda.

Yang sedang berkata, saya benci Git mengubah akhir baris saya. Kontrol sumber hanya akan menyimpan dan mengambil pekerjaan yang saya lakukan, itu TIDAK boleh memodifikasinya. Pernah. Tapi itu benar.

Apa yang akan terjadi jika Anda tidak membuat setiap pengembang disetel ke true, adalah SATU pengembang akhirnya akan disetel ke true. Ini akan mulai mengubah akhir baris semua file Anda ke LF di repo Anda. Dan ketika pengguna disetel ke false memeriksa itu, Visual Studio akan memperingatkan Anda, dan meminta Anda untuk mengubahnya. Anda akan memiliki 2 hal terjadi dengan sangat cepat. Satu, Anda akan mendapatkan semakin banyak peringatan itu, semakin besar tim Anda semakin banyak Anda dapatkan. Yang kedua, dan lebih buruk, adalah bahwa hal itu akan menunjukkan bahwa setiap baris dari setiap file yang diubah telah diubah (karena ujung baris dari setiap baris akan diubah oleh orang yang sebenarnya). Akhirnya, Anda tidak akan lagi dapat melacak perubahan dalam repo Anda. Jauh lebih mudah dan bersih untuk membuat semua orang tetap benar, daripada mencoba membuat semua orang salah. Sama mengerikannya dengan hidup dengan fakta bahwa kendali sumber tepercaya Anda melakukan sesuatu yang seharusnya tidak. Pernah.

JGTaylor
sumber
Perusahaan saya cukup kecil sehingga kami dapat dengan mudah mengamanatkan bahwa false digunakan di mana-mana, dan saya akan berpikir perusahaan yang lebih besar dapat melakukan ini melalui kebijakan, tetapi saya rasa ini adalah alasan yang sah untuk menggunakan "benar", jadi saya upvoting bagaimanapun. Terima kasih!
Kaya
1
Masalah dengan melakukan ini dengan kebijakan (file yang dipaksakan) adalah bahwa pada mesin windows Anda dapat memiliki file konfigurasi lokal, global, dan tersembunyi (ProgramData / Git / Confg). Anda dapat memberlakukan lokal dengan memeriksa ke dalam repo, tetapi Global DAN file yang tersembunyi diutamakan. Juga dimungkinkan untuk memiliki perbedaan lokal dan global (atau tersembunyi). Jika ya, mereka akan saling bertentangan pada mesin SAMA yang menyebabkan kesalahan akhir baris di mana tidak ada. Ini adalah rasa sakit untuk dilacak. :(
JGTaylor
7
persis apa yang saya pikirkan. itu bukan tugas kontrol sumber untuk mengacaukan file kode sesuka hati. akhir baris seharusnya hanya menjadi perhatian alat pengeditan, tidak lebih.
Tuncay Göncüoğlu
6
Jika proyek Anda hanya untuk Windows maka tidak ada masalah. Namun jika Anda atau kolega Anda bekerja pada platform * nix maka "rekomendasi kuat" Anda akan menimbulkan masalah. Coba jalankan skrip bash, perl atau python dengan shebang yang diakhiri \r\ndan Anda akan melihat.
phuclv
6
Situasi yang Anda gambarkan sebagai bukan masalah GIT, atur pengaturan ke FALSE sebagaimana biasanya dan itu hilang. Instad, itu adalah masalah dalam kerja tim. Apa artinya "akhirnya satu set pengembang true"? Mengapa Anda membiarkan mereka begitu saja? ketika Anda mengaturnya untuk mengakses git repo, maka sama seperti Anda tidak mengizinkan mencemari area-area tertentu dengan langs yang berbeda (jadi siapa pun yang mengerjakannya bisa membacanya), atau sama seperti Anda menyimpan cabang / gabungan / rebases / dll di sepanjang yang dipilih kebijakan, mereka harus mendapatkan aturan yang jelas: atur crlf yang benar.
quetzalcoatl
12

Pembaruan 2 :

Xcode 9 tampaknya memiliki "fitur" di mana ia akan mengabaikan akhir baris saat ini file, dan alih-alih hanya menggunakan pengaturan akhir baris default Anda ketika memasukkan baris ke dalam file, menghasilkan file dengan akhiran garis campuran.

Saya cukup yakin bug ini tidak ada di Xcode 7; tidak yakin tentang Xcode 8. Kabar baiknya adalah bahwa tampaknya diperbaiki dalam Xcode 10.

Untuk waktu itu ada, bug ini menyebabkan sejumlah kecil kegembiraan dalam basis kode yang saya rujuk dalam pertanyaan (yang sampai hari ini menggunakan autocrlf=false), dan menyebabkan banyak "EOL" melakukan pesan dan akhirnya ke saya menulis git pre-commithook untuk memeriksa untuk / mencegah memperkenalkan akhiran garis campuran.

Perbarui :

Catatan: Seperti yang dicatat oleh VonC, mulai dari Git 2.8, marka gabungan tidak akan memperkenalkan akhir baris gaya Unix ke file gaya Windows .

Asli :

Satu cegukan kecil yang saya perhatikan dengan pengaturan ini adalah ketika ada konflik penggabungan, baris git menambahkan untuk menandai perbedaan tidak memiliki akhir baris Windows, bahkan ketika sisa file tidak, dan Anda dapat berakhir dengan file dengan akhiran garis campuran, misalnya:

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

Ini tidak menimbulkan masalah bagi kami (saya bayangkan alat apa pun yang dapat menangani kedua jenis end-line juga akan masuk akal dengan campuran end-line - tentu saja semua yang kami gunakan lakukan), tetapi itu adalah sesuatu yang harus diperhatikan.

Hal lain * yang kami temukan, adalah ketika menggunakan git diffuntuk melihat perubahan pada file yang memiliki end-line Windows, baris yang telah ditambahkan akan menampilkan carriage return mereka, dengan demikian:

    // Not changed

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

* Itu tidak benar-benar pantas istilah: "masalah".

Kaya
sumber
2
NB Ketika Visual Studio menemukan file seperti itu, ia menawarkan untuk menormalkan akhir baris untuk Anda. Memilih akhir baris Windows atau memilih untuk tidak menormalkan akhir baris bekerja dengan baik (karena VS masih menampilkannya dengan benar, baris yang menyinggung akan dihapus setelah konflik telah diselesaikan).
Rich
2
Sayangnya kontrol versi perusahaan nazis tidak setuju dengan itu (LF pada penggabungan penanda konflik) tidak menjadi masalah.
Ilia G
1
Saya setuju bahwa LF pada penanda konflik gabungan seharusnya tidak menjadi masalah. Garis-garis itu seharusnya tidak dilakukan pada repo.
merampok
1
Catatan: mulai git 2.8 (Maret 2016), marka gabungan sebenarnya akan memiliki akhiran garis CRLF. Lihat stackoverflow.com/a/35474954/6309
VonC