Perché dovrei usare core.autocrlf = true in Git?


296

Ho un repository Git a cui si accede sia da Windows che da OS X e che so già contiene alcuni file con terminazioni di linea CRLF. Per quanto ne so, ci sono due modi per affrontarlo:

  1. Impostare core.autocrlfa falsetutto il mondo,

  2. Seguire le istruzioni qui (eco sulle pagine di aiuto di GitHub) per convertire il repository per contenere solo LF line-finali, e successivamente impostare core.autocrlfa truesu Windows e inputsu OS X. Il problema di questa operazione è che se ho tutti i file binari nel repository quello:

    1. non sono correttamente contrassegnati come binari in gitattributes e
    2. capita di contenere sia CRLF che LF,

    saranno corrotti. È possibile che il mio repository contenga tali file.

Quindi perché non dovrei semplicemente disattivare la conversione di fine riga di Git? Ci sono molti avvisi vaghi sul web di aver core.autocrlfspento causando problemi, ma pochissimi quelli specifici ; l'unico che ho scoperto finora è che kdiff3 non è in grado di gestire le terminazioni CRLF (non è un problema per me) e che alcuni editor di testo hanno problemi di fine riga (anche per me non è un problema).

Il repository è interno alla mia azienda, quindi non devo preoccuparmi di condividerlo con persone con diverse impostazioni di autocrlf o requisiti di fine riga.

Ci sono altri problemi nel lasciare le terminazioni così come sono di cui non sono a conoscenza?


1
Stackoverflow.com/questions/2333424/… sarebbe d' aiuto? Ho un link a motivi specifici per lasciare autocrlfa false.
VonC,

3
@VonC Grazie, ma sono già in grado di dettare che tutti gli utenti dell'azienda impostano <code> autocrlf </code> su false e attualmente ritengono che sia l'opzione migliore. Ma voglio sapere se ci sono dei motivi per cui non dovrei farlo, perché posso scoprire che ci sono molte persone (ad esempio GitHub) che affermano che dovrebbe essere impostato autocrlf ma non ci sono specifiche reali sul perché.
Ricco

3
@VonC cioè non sto cercando motivi per impostare autocrlfsu false. Sto cercando dei motivi per impostarlo su true.
Ricco

9
Perché non usarlo autocrlf = input: sembra essere la risoluzione perfetta tra i due estremi: mantieni il tuo repository pulito dalla merda CRLF e gli sviluppatori locali di Windows possono usare tutto ciò che vogliono senza che i loro file locali abbiano automaticamente qualcosa di magico. (Potrebbero volere LF localmente per vari motivi, quindi truesecondo me è un male.) Non riesco a vedere alcun lato negativo nell'uso autocrlf = input.
iconoclasta il

7
@iconclast, uno dei motivi per cui mi sono imbattuto è se si creano distribuzioni che includono sia file batch di Windows che script di shell Unix. Vuoi usare la fine della linea corretta in ogni caso, e questo è più difficile da fare se Git fa girare le cose in giro anche dopo averle esplicitamente impostate in un modo o nell'altro.
user1809090

Risposte:


227

Le ragioni solo specifico per la definizione autocrlfdi truesono:

  • evita di git statusmostrare tutti i tuoi file come a modifiedcausa della conversione EOL automatica fatta quando cloni un repository EOL Git basato su Unix in uno Windows (vedi il problema 83 per esempio)
  • e i tuoi strumenti di codifica dipendono in qualche modo dallo stile EOL nativo presente nel tuo file:

A meno che non si riesca a vedere un trattamento specifico che deve occuparsi di EOL nativo, è meglio lasciare autocrlfafalse ( git config --global core.autocrlf false).

Si noti che questa configurazione sarebbe locale (perché la configurazione non viene trasferita da repo a repo)

Se vuoi la stessa configurazione per tutti gli utenti che clonano quel repository, controlla " Qual è la migliore CRLFstrategia di gestione con git? ", Usando l' textattributo nel .gitattributesfile .

Esempio:

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

Nota: a partire da git 2.8 (marzo 2016), i marker di unione non introdurranno più la fine della linea mista (LF) in un file CRLF.
Vedi " Fai in modo che Git usi CRLF sulle sue linee di unione" <<<<<<< HEAD "


5
@VonC Grazie! Questo mi aiuta a sentirmi più sicuro che è sicuro per me usare autocrlf=false. Per interesse, sai perché git esegue ancora la conversione eol anche se autocrlf è impostato su false?
Ricco

14
@VonC: non penso che questa risposta sia corretta. L'uso di core.autocrlf = true su Windows funziona come previsto. Tutti i file dal repository (che dovrebbero avere terminazioni di linea LF in questo scenario) vengono convertiti in terminazioni di linea CRLF al momento del pagamento su un PC Windows. Tutti i file vengono riconvertiti in terminazioni di linea LF su commit da un PC Windows. Il modo per mettersi nei guai è effettuare il checkout inizialmente su un PC Windows con l'impostazione core.autocrlf errata (che è del tutto troppo facile da fare).
Michael Maddox,

3
@Michael Quindi, in quel caso, l'unica ragione per non usarlo core.autocrlf=falsenel mio scenario è se avessi qualche strumento / editor che si confonderebbe con i finali?
Rich

49
Userei sicuramente false, non sono mai stato un grande fan di cose automatiche o magiche che accadono in background. Basta usare \ne UTF-8ovunque e andrà tutto bene. Se un pazzo non capisce che ci sono convenzioni e regole e si dimentica di usare UTF-8o \n, allora qualcuno le converte manualmente e si schiaffeggia il viso.
Torre

5
@ Pauld'Aoust Preferirei ancora specificare il tipo di file che necessita di CRLF tramite gli core.eolattributi in un .gitattributesfile, piuttosto che usare questa core.autocrlfimpostazione globale che si applica indiscriminatamente a tutti i file.
VonC,

40

Sono uno sviluppatore .NET e uso Git e Visual Studio da anni. La mia forte raccomandazione è di impostare le terminazioni di riga su true. E fallo il prima possibile nella vita del tuo repository.

Detto questo, ODIO il fatto che Git cambi i miei finali. Un controllo del codice sorgente dovrebbe solo salvare e recuperare il lavoro che faccio, NON dovrebbe modificarlo. Mai. Ma lo fa.

Cosa succederà se non hai tutti gli sviluppatori impostati su true, UNO sviluppatore alla fine verrà impostato su true. Questo inizierà a cambiare le terminazioni di linea di tutti i tuoi file in LF nel tuo repository. E quando gli utenti impostano il falso per controllarli, Visual Studio ti avviserà e ti chiederà di cambiarli. Avrai 2 cose che succedono molto rapidamente. Uno, riceverai sempre più di quegli avvertimenti, più grande sarà la tua squadra e più otterrai. La seconda, e la cosa peggiore, è che mostrerà che ogni riga di ogni file modificato è stata cambiata (perché la fine di ogni riga sarà cambiata dal vero ragazzo). Alla fine non sarai più in grado di tenere traccia delle modifiche nel tuo repository in modo affidabile. È MOLTO più semplice e pulito rendere tutti fedeli alla verità, piuttosto che cercare di mantenere tutti falsi. Per quanto sia orribile convivere con il fatto che il tuo affidabile controllo del codice sorgente stia facendo qualcosa che non dovrebbe. Mai.


La mia azienda è abbastanza piccola da poter facilmente imporre che il falso sia usato ovunque, e avrei pensato che le aziende più grandi avrebbero potuto farlo tramite la politica, ma immagino che questo sia un motivo legittimo per usare "true", quindi sto votando Comunque. Grazie!
Ricco il

1
Il problema nel fare ciò con un criterio (file forzato) è che su un computer Windows è possibile avere un file di configurazione locale, globale e nascosto (ProgramData / Git / Confg). È possibile applicare il locale controllandolo nel repository, ma i file globali AND nascosti hanno la precedenza. Inoltre è possibile che locale e globale (o nascosto) siano diversi. In caso affermativo, entreranno in conflitto tra loro sulla macchina SAME causando errori di fine linea dove non ce ne sono. Questo è un dolore da rintracciare. :(
JGTaylor,

7
esattamente quello che penso. non è compito di un controllo del codice sorgente rovinare i file di codice come preferisce. le terminazioni di riga dovrebbero semplicemente riguardare gli strumenti di modifica, niente di più.
Tuncay Göncüoğlu,

6
Se il tuo progetto è solo per Windows, non ci sono problemi. Tuttavia, se tu o i tuoi colleghi lavorate su una piattaforma * nix, la vostra "raccomandazione forte" causerà problemi. Prova a eseguire uno script bash, perl o python con lo shebang che termina con \r\ne vedrai.
phuclv,

6
La situazione che hai descritto come non è un problema di GIT, imposta l'impostazione su FALSE come dovrebbe essere ed è andata. Instad, è un problema nel lavoro di squadra. Cosa significa "eventualmente imposta uno sviluppatore true"? Perché glielo permetteresti in primo luogo? quando li configuri per accedere a git repo, quindi proprio come non permetti di inquinare determinate aree con diversi lang (quindi chiunque lavori su di esso può leggerlo), o proprio come se mantieni rami / fusioni / rebase / ecc. lungo la scelta politica, dovrebbero ottenere una regola chiara: impostare crlf corretto.
quetzalcoatl,

12

Aggiornamento 2 :

Xcode 9 sembra avere una "caratteristica" in cui ignora i finali di riga correnti del file e utilizza invece l'impostazione di fine riga predefinita quando si inseriscono le righe in un file, risultando in file con finali di riga misti.

Sono abbastanza sicuro che questo errore non esistesse in Xcode 7; non sono sicuro di Xcode 8. La buona notizia è che sembra essere stato risolto in Xcode 10.

Per il tempo in cui è esistito, questo bug ha causato una piccola quantità di ilarità nella base di codice a cui mi riferisco nella domanda (che fino ad oggi utilizza autocrlf=false), e ha portato a molti messaggi di "EOL" e infine alla mia scrittura di un pre-commithook git per verificare per / prevenire l'introduzione di terminazioni di linea miste.

Aggiornamento :

Nota: Come notato da VonC, a partire dal Git 2.8, i marcatori di unione sarà non introdurrà stile Unix line-terminazioni in un file in stile Windows .

Originale :

Un piccolo inconveniente che ho notato con questa configurazione è che quando ci sono conflitti di unione, le linee aggiunte da git per evidenziare le differenze non hanno terminazioni di linea di Windows, anche quando il resto del file lo fa, e puoi finire con un file con terminazioni di riga miste, ad esempio:

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

Questo non ci causa alcun problema (immagino che qualsiasi strumento in grado di gestire entrambi i tipi di terminazioni di linea si occuperà anche di terminazioni di linea miste - certamente tutte quelle che usiamo fare), ma è qualcosa di cui essere consapevoli.

L'altra cosa * che abbiamo scoperto è che quando si utilizza git diffper visualizzare le modifiche a un file con terminazioni di linea di Windows, le linee che sono state aggiunte mostrano i loro ritorni a capo, quindi:

    // Not changed

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

* In realtà non merita il termine: "problema".


2
NB Quando Visual Studio rileva un file del genere, si offre di normalizzare le terminazioni di linea per te. Scegliere le terminazioni di linea di Windows o scegliere di non normalizzare le terminazioni di linea funziona correttamente (poiché VS lo visualizza ancora correttamente, le linee offensive saranno state eliminate una volta risolto il conflitto).
Rich

2
Sfortunatamente i nazisti di controllo delle versioni aziendali non sono d'accordo (LF sui merge markers) non è un problema.
Ilia G

1
Concordo sul fatto che LF sui merge marker non dovrebbe essere un problema. Tali linee non dovrebbero comunque essere impegnate nel pronti contro termine.
ruba il

1
Nota: a partire da git 2.8 (marzo 2016), i marker di unione avranno effettivamente la fine della linea CRLF. Vedere stackoverflow.com/a/35474954/6309
VonC
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.