Come posso forzare git a usare LF invece di CR + LF sotto Windows?


335

Voglio forzare git a fare il checkout dei file in Windows usando semplicemente LFno CR+LF. Ho controllato le due opzioni di configurazione ma non sono riuscito a trovare la giusta combinazione di impostazioni.

Voglio che converta tutti i file LFe mantenga LFi file.

Nota: l'ho usato autocrlf = inputma questo ripristina solo i file quando li commetti. Voglio forzarlo per farli usare LF.

Probabilmente non ero così chiaro: il repository sta già usando LFma i file estratti usando msysgit stanno usando CR+LFe voglio forzare msysgit per ottenerli con LF: forzare i finali di linea Unix .

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

2
autocrlf=inputè l'opzione corretta. Ovviamente non ti protegge dai file che hanno veramente cr+lfnel repository o dalla creazione di file con cr+lfun altro strumento prima di aggiungerli a git. Per quali problemi hai che non funziona?
CB Bailey

2
I file nel repository stanno già utilizzando solo, LFma quando li trovo sotto msysgit di Windows li converte CR+LF.
sorin,

Deve esserci qualcosa nella tua configurazione; Ho appena provato questo sulla mia installazione di msysgit. Con autocrlfset su input, git sta lasciando lfsoli gli avanzamenti di riga. Puoi pubblicare l'output di git config?
CB Bailey

1
In tal caso, ti suggerisco di registrare un bug; preferibilmente indicando un repository di prova che presenta il tuo problema e includendo i passaggi da riprodurre poiché il comportamento che stai vedendo è decisamente sbagliato (ma non riesco a riprodurlo).
CB Bailey,

1
Un piccolo suggerimento è assicurarsi anche di eseguire i comandi git sul 'git' che si pensa di essere. Ad esempio, potresti avere git installato su Windows e git installato su Cygwin, quindi assicurati di aver impostato la corretta configurazione di git.
venerdì

Risposte:


106

L'OP ha aggiunto alla sua domanda:

i file estratti usando msysgit stanno usando CR+LFe voglio forzare msysgit per ottenerliLF

Un primo semplice passo sarebbe ancora in un .gitattributesfile:

# 2010
*.txt -crlf

# 2020
*.txt text eol=lf 

(come notato nei commenti del nipote , facendo riferimento alla .gitattributesconversione di fine riga ), per evitare qualsiasi CRLFconversione per i file con corretto eol.

E ho sempre consigliato git config --global core.autocrlf false di disabilitare qualsiasi conversione (che si applicherebbe a tutti i file con versione)

Vedi le migliori pratiche per config git multipiattaforma?

Da Git 2.16 (Q1 2018), è possibile utilizzare git add --renormalize .per applicare .gitattributesimmediatamente tali impostazioni.


Ma un secondo passaggio più potente prevede un driver di filtro gitattribute e aggiunge un passaggio sfumato

driver del filtro

Ogni volta che aggiorni l'albero di lavoro, uno script potrebbe, solo per i file che hai specificato in .gitattributes, forzare LF eole qualsiasi altra opzione di formattazione che desideri applicare.
Se lo clearscript " " non fa nulla, avrai (dopo il commit) trasformato i tuoi file, applicando esattamente il formato che devi seguire.


Una domanda: * .txt si riferisce a tutti i file con estensione .txt o a tutti i file di testo (non binari)? Non riesco a fare un elenco con tutti i tipi di estensione di file che avrò nel progetto.
sorin,

1
@Sorin: tutti i file con .txtestensione. È preferibile prima stabilirlo e testarlo su un gruppo specifico, prima di generalizzare a *, e aggiungere una regola negativa !*.xyz ...per escludere alcuni file da quella regola.
VonC,

1
Ormai le .gitattributesrighe dovrebbero essere: *.txt text eol=lfcome da git-scm.com/docs/gitattributes
nipote

@grandchild Grazie. Ho incluso il tuo commento nella risposta per una maggiore visibilità.
VonC

Immagino che dopo aver aggiunto .gitattributesche dobbiamo faregit add --renormalize .
shuva

461

Il modo corretto per ottenere le terminazioni LF in Windows è innanzitutto impostare core.autocrlfsu false:

git config --global core.autocrlf false

Devi farlo se stai usando msysgit, perché lo imposta truenelle sue impostazioni di sistema.

Ora git non eseguirà alcuna linea che termina la normalizzazione. Se si desidera che i file in cui si effettua il check-in siano normalizzati, procedere come segue: Impostare text=autoin .gitattributesper tutti i file

* text=auto

E impostare core.eolsu lf:

git config --global core.eol lf

Ora puoi anche passare singoli repository a crlf (nella directory di lavoro!) Eseguendo

git config core.eol crlf

Dopo aver effettuato la configurazione, potresti voler git per normalizzare tutti i file nel repository . Per fare ciò, vai alla radice del tuo repository ed esegui questi comandi:

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

Se ora vuoi che git normalizzi anche i file nella tua directory di lavoro , esegui questi comandi:

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

3
Sto diventando fatal pathspec '' non corrisponde ad alcun file, subito dopogit diff --cached --name-only -z | xargs -0 git add
CMCDragonkai

3
Qual è l'output di git diff --cached --name-only?
Cronologico

1
Vale la pena ricordare che è possibile impostare questa configurazione durante la clonazione del repository in questione, ad es git clone --config core.autocrlf=false <repo path>.
Chris Long,

240

Torno a questa risposta abbastanza spesso, sebbene nessuna di queste sia giusta per me. Detto questo, la risposta giusta per me è un misto degli altri.

Quello che trovo funziona è il seguente:

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

Per i repository che sono stati estratti dopo che sono state impostate quelle impostazioni globali, tutto verrà verificato come qualunque cosa sia nel repository - si spera LF( \n). Qualsiasi CRLFverrà convertito in appena LFal momento del check-in.

Con un repository esistente che è già stato estratto, che presenta le terminazioni di riga corrette nel repository ma non la copia di lavoro, è possibile eseguire i seguenti comandi per risolverlo:

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

Questo eliminerà ( rm) in modo ricorsivo ( r) senza prompt ( -f), tutti i file tranne quelli che hai modificato ( --cached), dalla directory corrente ( .). Ilreset allora restituisce tutti i file a uno stato dove hanno i loro fine riga veri (corrispondenti che cosa è nella repo).

Se hai bisogno di correggere le terminazioni di riga dei file in un repository, ti consiglio di prendere un editor che ti consenta di farlo in blocco come IntelliJ o Sublime Text, ma sono sicuro che qualcuno di buono probabilmente lo supporterà.


1
Abbiamo un unico repository con sottodirectory che richiedono una gestione diversa del finale di linea. Quindi l'impostazione di un'opzione globale non funziona per questo. Nemmeno nel singolo repository. Come si applicano queste stesse impostazioni in .gitattributes?
RobG,

Notepad++mostra anche la fine della riga del file aperto corrente nell'angolo in basso a destra. Un clic destro su quel campo ti permetterà di cambiare le terminazioni di linea.
winklerrr,

1
L' core.autocrlf inputopzione sovrascrive l' core.eolimpostazione, quindi l'impostazione di entrambi è ridondante. (Vedi git-scm.com/docs/git-config )
Andrew Marshall il

1
Grazie, con il tuo aiuto ho conquistato lint e Linux. E ora può archiviare i file.
GC_

57

Contesto

Se tu

  1. vogliono forzare tutti gli utenti ad avere terminazioni di riga LF per file di testo e
  2. non puoi assicurarti che tutti gli utenti cambino la loro configurazione git,

puoi farlo iniziando con git 2.10. È richiesto 2.10 o successivo, perché 2.10 ha risolto il comportamento di text = auto insieme a eol = lf . Fonte .

Soluzione

Inserisci un .gitattributesfile nella radice del tuo repository git con i seguenti contenuti:

* text=auto eol=lf

Commettilo.

Modifiche opzionali

È inoltre possibile aggiungere un elemento .editorconfignella radice del repository per assicurarsi che gli strumenti moderni creino nuovi file con le terminazioni di riga desiderate.

# 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
Questa è stata la soluzione migliore per me. Ho anche combinato questo con editorconfig.org in modo che quando scrivo in Intellij avrei scritto LF EOLs.
Jazzepi,

Questa è di gran lunga la soluzione migliore. Non è necessario eseguire manualmente alcun comando di configurazione!
Cameron Tacklind,

26

core.autocrlf=inputè l'impostazione giusta per quello che vuoi, ma potresti dover fare un git update-index --refreshe / o un git reset --hardper rendere effettiva la modifica.

Con core.autocrlfimpostato su input, git non applicherà la conversione di newline al momento del check-out (quindi se hai LF nel repository, otterrai LF), ma si assicurerà che in caso tu sbagli e introduca alcuni CRLF nel funzionamento copia in qualche modo, non si faranno strada nel repository.


19
I comandi dovrebbero essere git rm --cached -r. && git reset --hard
koppor

0

Puoi trovare la soluzione a questo problema su: https://help.github.com/en/github/using-git/configuring-git-to-handle-line-endings

Descrizione semplificata di come risolvere questo problema su Windows:

Impostazioni globali per i finali di riga Il comando git config core.autocrlf viene utilizzato per modificare il modo in cui Git gestisce i finali di linea. Ci vuole un solo argomento.

Su Windows, passi semplicemente true alla configurazione. Ad esempio: C:> git config --global core.autocrlf true

Buona fortuna, spero di aver aiutato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.