Bagaimana cara memaksa git untuk menggunakan LF daripada CR + LF di bawah windows?


335

Saya ingin memaksa git untuk checkout file di bawah Windows menggunakan LFtidak CR+LF. Saya memeriksa dua opsi konfigurasi tetapi saya tidak dapat menemukan kombinasi pengaturan yang tepat.

Saya ingin itu mengkonversi semua file ke LFdan tetap LFdi file.

Catatan: Saya menggunakan autocrlf = inputtetapi ini hanya memperbaiki file ketika Anda mengkomitnya. Saya ingin memaksanya untuk menggunakannya LF.

Mungkin saya tidak begitu jelas: repositori sudah menggunakan LFtetapi file-file yang diperiksa menggunakan msysgit menggunakan CR+LFdan saya ingin memaksa msysgit untuk mendapatkannya dengan LF: memaksa ujung garis Unix .

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

2
autocrlf=inputadalah pilihan yang benar. Tentu saja itu tidak melindungi Anda dari file yang benar-benar ada cr+lfdi repositori atau membuat file dengan cr+lfalat lain sebelum menambahkannya ke git. Apa masalah yang Anda alami sehingga ini tidak berhasil?
CB Bailey

2
File-file di repositori hanya menggunakan LFtetapi ketika saya mendapatkannya di Windows msysgit mengubahnya menjadi CR+LF.
sorin

Pasti ada sesuatu dengan konfigurasi Anda; Saya baru saja menguji ini di install msysgit saya. Dengan autocrlfset ke input, git meninggalkan lfumpan baris sendirian. Bisakah Anda memposting output git config?
CB Bailey

1
Dalam hal ini, saya sarankan Anda mencatat bug; lebih baik menunjuk ke repositori tes yang menunjukkan masalah Anda dan termasuk langkah-langkah untuk mereproduksi karena perilaku yang Anda lihat sudah pasti salah (tapi saya tidak bisa mereproduksi itu).
CB Bailey

1
Tip kecil adalah juga memastikan Anda menjalankan perintah git pada 'git' yang Anda kira. Sebagai contoh, Anda mungkin telah menginstal git di windows, dan git diinstal di cygwin, jadi pastikan Anda telah mengatur konfigurasi git yang tepat.
lfred

Jawaban:


106

OP menambahkan dalam pertanyaannya:

file-file diperiksa menggunakan msysgit menggunakan CR+LFdan saya ingin memaksa msysgit untuk mendapatkannyaLF

Langkah sederhana pertama masih akan di .gitattributesfile:

# 2010
*.txt -crlf

# 2020
*.txt text eol=lf 

(seperti yang tercantum dalam komentar oleh cucu , merujuk pada .gitattributeskonversi End-of-line ), untuk menghindari CRLFkonversi untuk file dengan benar eol.

Dan saya selalu merekomendasikan git config --global core.autocrlf false untuk menonaktifkan konversi apa pun (yang akan berlaku untuk semua file versi)

Lihat Praktik terbaik untuk konfigurasi lintas platform git?

Sejak Git 2.16 (Q1 2018), Anda dapat menggunakan git add --renormalize .untuk .gitattributessegera menerapkan pengaturan itu.


Tetapi langkah kedua yang lebih kuat melibatkan driver filter gitattribute dan menambahkan langkah noda

driver filter

Setiap kali Anda memperbarui pohon kerja Anda, sebuah skrip bisa, hanya untuk file yang telah Anda tentukan di .gitattributes, memaksa LF eoldan opsi pemformatan lain yang Anda ingin menegakkan.
Jika clearskrip " " tidak melakukan apa-apa, Anda akan (setelah komit) mengubah file Anda, menerapkan persis format yang Anda butuhkan untuk diikuti.


Satu pertanyaan: * .txt merujuk ke semua file dengan ekstensi .txt atau ke semua file teks (bukan biner)? Saya tidak dapat membuat daftar dengan semua jenis ekstensi file yang akan saya miliki dalam proyek ini.
sorin

1
@ Korin: semua file dengan .txtekstensi. Lebih baik untuk membuat ini pertama dan mengujinya pada kelompok tertentu, sebelum generalisasi ke *, dan menambahkan aturan negatif !*.xyz ...untuk mengecualikan beberapa file dari aturan itu.
VonC

1
Sekarang .gitattributesbaris tersebut seharusnya sudah terbaca: *.txt text eol=lfsesuai git-scm.com/docs/gitattributes
grandchild

@grandchild Terima kasih. Saya telah memasukkan komentar Anda dalam jawaban untuk lebih banyak visibilitas.
VonC

Saya kira setelah kita menambahkan yang .gitattributesharus kita lakukangit add --renormalize .
shuva

461

Cara yang tepat untuk mendapatkan ujung LF di Windows adalah dengan terlebih dahulu diatur core.autocrlfke false:

git config --global core.autocrlf false

Anda perlu melakukan ini jika Anda menggunakan msysgit, karena ia menetapkannya truedalam pengaturan sistemnya.

Sekarang git tidak akan melakukan normalisasi akhir baris. Jika Anda ingin file Anda check in ke dinormalisasi, lakukan ini: Set text=autodi Anda .gitattributesuntuk semua file:

* text=auto

Dan mengatur core.eol ke lf:

git config --global core.eol lf

Sekarang Anda juga dapat mengganti satu repo ke crlf (di direktori kerja!) Dengan menjalankan

git config core.eol crlf

Setelah Anda selesai melakukan konfigurasi, Anda mungkin ingin git menormalkan semua file di repo . Untuk melakukan ini, buka ke root repo Anda dan jalankan perintah ini:

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

Jika sekarang Anda ingin git juga menormalkan file di direktori kerja Anda , jalankan perintah ini:

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

3
Saya mendapatkan pathspec yang fatal '' tidak cocok dengan file mana pun, tepat setelahgit diff --cached --name-only -z | xargs -0 git add
CMCDragonkai

3
apa output dari git diff --cached --name-only?
Kronik

1
Mungkin perlu disebutkan bahwa Anda dapat mengatur konfigurasi ini saat kloning repo yang bersangkutan, misalnya git clone --config core.autocrlf=false <repo path>.
Chris Long

240

Saya kembali ke jawaban ini cukup sering, meskipun tidak ada yang cocok untuk saya. Yang mengatakan, jawaban yang tepat bagi saya adalah campuran dari yang lain.

Yang saya temukan adalah yang berikut:

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

Untuk repo yang diperiksa setelah pengaturan global itu ditetapkan, semuanya akan diperiksa seperti apa pun yang ada dalam repo - semoga LF( \n). Apa CRLFpun akan dikonversi menjadi hanya LFpada checkin.

Dengan repo yang sudah ada yang sudah Anda periksa - yang memiliki akhiran baris yang benar dalam repo tetapi bukan copy pekerjaan Anda - Anda dapat menjalankan perintah berikut untuk memperbaikinya:

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

Ini akan menghapus ( rm) secara rekursif ( r) tanpa prompt ( -f), semua file kecuali yang telah Anda edit ( --cached), dari direktori saat ini ( .). Itureset kemudian mengembalikan semua file-file ke keadaan di mana mereka memiliki akhir baris sejati mereka (matching apa yang ada di repo).

Jika Anda perlu memperbaiki akhiran baris file dalam repo, saya sarankan Anda mengambil editor yang memungkinkan Anda melakukannya secara massal seperti IntelliJ atau Sublime Text, tapi saya yakin ada yang bagus kemungkinan akan mendukung ini.


1
Kami memiliki satu repo dengan sub direktori yang memerlukan penanganan akhir baris yang berbeda. Jadi pengaturan opsi global tidak berfungsi untuk ini. Bahkan dalam repo tunggal. Bagaimana Anda menerapkan pengaturan yang sama ini di .gitattributes?
RobG

Notepad++juga menunjukkan akhir baris dari currenlty file yang dibuka di sudut kanan bawah. Klik kanan pada bidang itu akan memungkinkan Anda untuk mengubah akhir baris.
winklerrr

1
The core.autocrlf inputpilihan menimpa core.eolpengaturan, sehingga pengaturan kedua adalah berlebihan. (Lihat git-scm.com/docs/git-config )
Andrew Marshall

1
Terima kasih, dengan bantuan Anda, saya telah mengalahkan serat dan Linux. Dan sekarang bisa check in file.
GC_

57

Konteks

Jika kamu

  1. ingin memaksa semua pengguna untuk memiliki akhiran garis LF untuk file teks dan
  2. Anda tidak dapat memastikan bahwa semua pengguna mengubah konfigurasi git mereka,

Anda bisa melakukannya mulai dengan git 2.10. Diperlukan 2.10 atau lebih baru, karena 2.10 memperbaiki perilaku text = auto bersama dengan eol = lf . Sumber .

Larutan

Letakkan .gitattributesfile di root repositori git Anda yang memiliki konten berikut:

* text=auto eol=lf

Lakukan itu.

Tweak opsional

Anda juga dapat menambahkan .editorconfigdi root repositori Anda untuk memastikan bahwa perkakas modern membuat file baru dengan akhiran baris yang diinginkan.

# 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
Ini solusi terbaik bagi saya. Saya juga menggabungkan ini dengan editorconfig.org sehingga ketika menulis di Intellij saya akan menulis LF EOLs.
Jazzepi

Sejauh ini, ini adalah solusi terbaik. Tidak perlu menjalankan perintah konfigurasi secara manual!
Cameron Tacklind

26

core.autocrlf=inputadalah pengaturan yang tepat untuk apa yang Anda inginkan, tetapi Anda mungkin harus melakukan git update-index --refreshdan / atau git reset --hardagar perubahan tersebut berlaku.

Dengan core.autocrlfset to input, git tidak akan menerapkan konversi baris baru saat check-out (jadi jika Anda memiliki LF di repo, Anda akan mendapatkan LF), tetapi itu akan memastikan bahwa jika Anda mengacaukan dan memperkenalkan beberapa CRLF dalam bekerja salin entah bagaimana, mereka tidak akan masuk ke repo.


19
Perintah harus git rm --cached -r. && git reset --hard
koppor

0

Anda dapat menemukan solusi untuk masalah ini di: https://help.github.com/en/github/using-git/configuring-git-to-handle-line-endings

Deskripsi sederhana tentang bagaimana Anda dapat memecahkan masalah ini di windows:

Pengaturan global untuk akhir baris Perintah git config core.autocrlf digunakan untuk mengubah cara Git menangani akhir baris. Dibutuhkan satu argumen.

Di Windows, Anda cukup meneruskan true ke konfigurasi. Sebagai contoh: C:> git config --global core.autocrlf true

Semoga beruntung, saya harap saya membantu.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.