Nonaktifkan Konversi git EOL

101

Saya mencoba membuat git tidak mengubah akhir baris apa pun untuk operasi apa pun. Sayangnya, tampaknya demikian tidak peduli apa. Saya telah menguranginya menjadi kasus uji berikut, yang memiliki mekanisme berbeda untuk menonaktifkan perilaku ini sebanyak yang dapat saya temukan.


  • Mulailah dengan dua mesin (komputer Windows = A, komputer Linux = B)
  • Di kedua mesin: git config --global core.autocrlf false
  • Di kedua mesin: git config --global core.eol crlf(untuk berjaga-jaga)

  • Buat repositori baru di A. Dari folder kosong:
    • git init --shared(lalu perlihatkan .gitdirektori yang dibuat )
    • Buat file baru .gitignoredi repositori
    • Buat file baru .gitattributesdi repositori dengan satu baris:* -text
    • git add ., lalu git commit -m "initial commit"untuk menyiasatinya, misalnya ini .
    • git branch master_recv
    • Tambahkan remote
  • Buat file baru document.txtdi repositori yang berisi CRLF
  • Komit:, git add -Alalugit commit -m "<something>"
  • Perhatikan bahwa A document.txtmasih berisi CRLF (dan menghapusnya dan mengatur ulang dengan --hardmengembalikan versi yang masih dengan CRLF)

  • SCP seluruh direktori ke komputer B
  • Tambahkan file baru yang new fileberisi CRLF
  • Melakukan: git add -Alalugit commit -m "<something>"
  • Perhatikan bahwa B document.txtdan B new filekeduanya masih mengandung CRLF

  • Tarik master B ke A: git pull <remote> master:master_recv
  • A document.txttelah berubah menjadi LF. File yang ditambahkan new filejuga berisi LF.

Masalah tidak terjadi jika B adalah mesin Windows.

imallett.dll
sumber
Apakah core.autocrlf selalu salah? Sepertinya Anda sudah memiliki \nakhiran baris di repositori Anda? Tidak ada pengaturan untuk diubah \ndalam repositori Anda ke \r\ndalam direktori kerja Anda.
Edward Thomson
Itu tidak selalu diatur (misalnya ketika repo dibuat aslinya). Namun, seharusnya tidak ada akhir baris CR di repo. Juga, sekali lagi, saya tidak ingin ada perubahan apa pun yang terjadi.
imallett
Saya bertanya karena penyiapan Anda harus mempertahankan akhiran baris Anda sebagai CRLF. Bisakah Anda memposting beberapa file di repositori Anda dengan ID objeknya hanya untuk perbaikan saya (memang mungkin mengganggu)?
Edward Thomson
@EdwardThomson apa maksudmu? Repo ini bukan untuk publik (karena mesin Linux tidak). Saya akan berasumsi Anda menginginkan file contoh. Lihat edit.
imallett
Ya, saya setuju bahwa file tersebut memiliki akhiran baris CRLF. Dapatkah Anda menjelaskan satu hal: Anda menyebutkan bahwa "baris baru mesin windows berubah menjadi CR!" Tentunya itu salah ketik, atau apakah Anda benar-benar mendapatkan akhiran baris pengembalian kereta bergaya Mac OS 9?
Edward Thomson

Jawaban:

75

Di dalam proyek Anda, harus ada .gitattributesfile. Biasanya, ini akan terlihat seperti di bawah (atau cuplikan layar ini ):

# 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

Ubah * text=autoke * text=falseuntuk menonaktifkan penanganan otomatis (lihat tangkapan layar ).

Seperti ini:

masukkan deskripsi gambar di sini

Jika proyek Anda tidak memiliki file .gitattributes, maka akhiran baris disetel oleh konfigurasi git Anda. Untuk mengubah konfigurasi git Anda, lakukan ini:

Buka file konfigurasi di direktori ini:

1) C: \ ProgramData \ Git \ config

2) Buka file konfigurasi di Notepad ++ (atau editor teks apa pun yang Anda inginkan)

3) Ubah "autocrlf =" menjadi false.

masukkan deskripsi gambar di sini

Gen
sumber
31
Mengapa menggunakan gambar sebagai ganti tag kode? Sangat tidak nyaman
Clint
31
Karena saya bisa menambahkan kotak merah besar pada gambar untuk menyorot sesuatu.
Gene
21
Using * text=falsenot unset text: membiarkan teks disetel ke nilai string salah. Ini memiliki efek yang sama dengan membiarkan teks tidak ditentukan (tidak secara khusus tidak disetel). Menggunakan * -textmemberikannya pengaturan khusus yang tidak disetel. Membatalkan pengaturan atribut teks di jalur memberitahu git untuk tidak mencoba konversi akhir baris apa pun saat check in atau checkout.
JustAMartin
Terima kasih @Gene untuk jawaban ini. Ini membuatku gila sepanjang hari, dan yang ini menyelesaikannya untukku!
LeopardSkinPillBoxHat
7
Maaf untuk mengatakan bahwa saya tidak dapat mengucapkan terima kasih atas jawaban ini. Habiskan waktu setengah hari untuk mengetahui bahwa seseorang telah mengikuti nasihat yang menyesatkan. Seperti yang dikatakan @JustAMartin * text=falsetidak berpengaruh. Harap perbaiki jawabannya!
Paul B.
49

Salah satu solusi sederhana adalah:

  • pastikan core.autocrlf disetel ke false untuk semua repo:
    git config --global core.autocrlf false
  • kloning ulang repo Anda, dan periksa apakah konversi EOL sudah selesai.
  • atau, sejak Git 2.16 (Q1 2018) , pertahankan repo Anda saat ini, dan lakukan agit add --renormalize .

Jika ada konversi yang dilakukan secara otomatis, itu berarti ada .gitattributes core.eolarahan di dalam repo.

Dengan Git 2.8+ (Maret 2016) , periksa apakah masih ada transformasi eol dengan:

git ls-files --eol
VonC
sumber
3
HANYA JANGAN GUNAKAN autocrlfHARI INI! unsetted autocrlfsetara dengan false. Anda tertinggal di belakang pergerakan trendi di Git
Lazy Badger
1
Seperti di atas, saya telah mencoba ini (meskipun tidak dengan bendera global), dan tidak berhasil. versi git adalah 1.8.5.2.
imallett
@IanMallett "Pada titik ini, tampaknya mesin Linux masih memiliki CRLF": itu akan sampai Anda menormalkan ulang kontennya, atau mengkloningnya (seperti yang Anda lakukan di windows)
VonC
Jika Anda mencoba membuat ini hanya untuk satu repo maka jalankan saja git config core.autocrlf false- menyebutkan ini karena umumnya autocrlf harus trueuntuk windows dan inputuntuk orang lain, tetapi terkadang Anda memerlukan sesuatu yang spesifik untuk kasus edge yang aneh. Dalam kasus saya, saya telah mengunduh beberapa file dan ingin mencatat perubahan yang saya buat sehingga saya dapat mengingat apa yang telah saya lakukan (bukan melacak perubahan pada kode). Saya tidak tahu apakah akhiran baris itu penting (dan ingin perbedaannya masuk akal dibandingkan dengan "yang sebenarnya") jadi saya menonaktifkan autocrlf.
Captain Man
11

Saya menemukan jawabannya. Tampaknya program SCP mengubah akhir baris. Saya perhatikan ini ketika saya mencoba dengan sengaja membuat file dengan akhiran LF dan kemudian mengamati bahwa itu muncul sebagai CRLF saat diunduh.

Karena ini adalah solusi untuk saya, saya menerima jawaban ini, tetapi orang-orang di masa depan juga harus mengacu pada jawaban lain untuk solusi yang lebih umum.

imallett.dll
sumber
1
Tangkapan bagus, lebih spesifik dari jawaban saya. +1
VonC
4

Dari gitattributes (5) Halaman Manual topik "Efek"

text

Atribut ini mengaktifkan dan mengontrol normalisasi end-of-line. Ketika file teks dinormalisasi, ujung barisnya diubah menjadi LF di repositori. Untuk mengontrol gaya akhiran baris apa yang digunakan di direktori kerja, gunakan eolatribut untuk satu file dan core.eol variabel konfigurasi untuk semua file teks.

Set

Menyetel atribut teks pada jalur memungkinkan normalisasi akhir baris dan menandai jalur sebagai file teks. Konversi akhir baris terjadi tanpa menebak jenis konten.

Unset Membatalkan pengaturan atribut teks di jalur memberitahu Git untuk tidak mencoba konversi akhir baris apa pun pada saat check in atau checkout.

core.autocrlfdi (1.7.2+) baru Git tidak digunakan, core.eoldan pengaturan yang benar | penghapusan atribut teks dianggap sebagai cara yang lebih dapat diandalkan

Malas Badger
sumber
Dalam .gitattributesfile tersebut, saya telah secara eksplisit menonaktifkan semuanya sebagai teks, bukan? Juga, saya tidak melihatnya dengan opsi untuk membuatnya tidak melakukan konversi (meskipun crlfmungkin tidak berpengaruh)?
imallett
6
Hal penting yang sering membuat bingung - untuk membatalkan textdan mencegah konversi apa pun, Anda harus menetapkan .gitattributes ke * -text dan tidak ke * text=false. falsebukan nilai yang valid untuk textatribut - git tidak akan mengenalinya dan sebagai gantinya akan kembali ke pengaturan autocrlf default. Selain itu, setelah mengubah textnilai, Anda harus mencadangkan semua file dari repo lokal Anda, melakukan komit, lalu memulihkan file dengan ujung baris yang benar sesuai kebutuhan, dan memasukkannya kembali. Kemudian akhir baris Anda tidak akan pernah dimodifikasi oleh git lagi.
JustAMartin