Disabilita le conversioni EOL di git


100

Sto cercando di convincere git a non cambiare alcuna fine di riga per nessuna operazione. Sfortunatamente, sembra che sia così non importa cosa. L'ho ridotto al seguente test case, che ha tanti meccanismi diversi per disabilitare questo comportamento come ho potuto trovare.


  • Inizia con due macchine (computer Windows = A, computer Linux = B)
  • Su entrambe le macchine: git config --global core.autocrlf false
  • Su entrambe le macchine: git config --global core.eol crlf(per ogni evenienza)

  • Crea un nuovo repository su A. Da una cartella vuota:
    • git init --shared(quindi mostra la .gitdirectory creata )
    • Crea un nuovo file .gitignorenel repository
    • Crea un nuovo file .gitattributesnel repository con la singola riga:* -text
    • git add ., quindi git commit -m "initial commit"per aggirare, ad esempio questo .
    • git branch master_recv
    • Aggiungi telecomandi
  • Crea un nuovo file document.txtnel repository contenente CRLF
  • Impegnati:, git add -Aalloragit commit -m "<something>"
  • Nota che A document.txtcontiene ancora CRLF (e cancellandolo e ripristinandolo con --hardrestituisce la versione ancora con CRLF)

  • SCP l'intera directory sul computer B
  • Aggiungi un nuovo file new filecontenente CRLF
  • Impegnati:, git add -Aalloragit commit -m "<something>"
  • Notare che B document.txte B new filecontengono entrambi CRLF

  • Porta il master di B su A: git pull <remote> master:master_recv
  • A's document.txtè cambiato in LF. Il file aggiunto new filecontiene anche LF.

Il problema non si verifica se B è una macchina Windows.


È core.autocrlf sempre stato falso? Sembra che tu abbia già delle \nterminazioni di riga nel tuo repository? Non v'è alcuna impostazione per modificare \nnel vostro repository per \r\nnella directory di lavoro.
Edward Thomson

Non è sempre stato impostato (ad esempio quando il repo è stato creato originariamente). Tuttavia, non dovrebbero esserci già terminazioni di riga CR nel repo. Inoltre, ancora una volta, non voglio che avvengano cambiamenti di sorta.
imallett

Chiedo perché la tua configurazione dovrebbe preservare le terminazioni di riga come CRLF. Potresti pubblicare qualche file nel tuo repository con il suo ID oggetto solo per la mia (certamente probabilmente fastidiosa) edificazione?
Edward Thomson

@EdwardThomson come intendi? Il repository non è pubblico (poiché la macchina Linux non lo è). Presumo che tu voglia un file di esempio. Vedi modifica.
imallett

Sì, sono d'accordo che quel file abbia terminazioni di riga CRLF. Puoi chiarire una cosa: hai detto che "i newline di Windows Machine cambiano in CR!" Sicuramente è stato un errore di battitura, o stai davvero ottenendo le terminazioni di ritorno a capo in stile Mac OS 9?
Edward Thomson

Risposte:


74

All'interno del tuo progetto dovrebbe esserci un .gitattributesfile. Il più delle volte, dovrebbe apparire come di seguito (o questa schermata ):

# 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

Modificare * text=autoin * text=falseper disabilitare la gestione automatica (vedere la schermata ).

Come questo:

inserisci qui la descrizione dell'immagine

Se il tuo progetto non ha un file .gitattributes, le terminazioni di riga sono impostate dalle tue configurazioni git. Per modificare le tue configurazioni git, fai questo:

Vai al file di configurazione in questa directory:

1) C: \ ProgramData \ Git \ config

2) Apri il file di configurazione in Notepad ++ (o qualsiasi editor di testo che preferisci)

3) Cambia "autocrlf =" in false.

inserisci qui la descrizione dell'immagine


31
Perché usare immagini invece di tag di codice? Molto scomodo
Clint

31
Perché posso aggiungere una grande scatola rossa nella foto per evidenziare le cose.
Gene

21
L'utilizzo * text=falsenon annulla l'impostazione del testo: lascia il testo impostato sul valore della stringa false. Questo ha lo stesso effetto che lasciare il testo non specificato (non specificatamente non impostato). L'utilizzo * -textdà la speciale impostazione non impostata. Il disinserimento dell'attributo text su un percorso dice a git di non tentare alcuna conversione di fine riga al momento del checkin o del checkout.
JustAMartin

Grazie @Gene per questa risposta. Questo mi ha fatto impazzire tutto il giorno e questo mi ha risolto!
LeopardSkinPillBoxHat

7
Mi dispiace dover dire che non posso ringraziare per questa risposta. Mi è costata mezza giornata per scoprire che qualcuno aveva seguito il consiglio fuorviante. Come ha sottolineato @JustAMartin * text=falsenon ha effetto. Si prega di correggere la risposta!
Paul B.

47

Una semplice soluzione è:

  • assicurati che core.autocrlf sia impostato su false per tutti i repository:
    git config --global core.autocrlf false
  • clona nuovamente il tuo repository e controlla che non sia stata eseguita alcuna conversione EOL.
  • oppure, a partire da Git 2.16 (Q1 2018) , mantieni il tuo attuale repository e fai un filegit add --renormalize .

Se vengono eseguite automaticamente conversioni, significa che all'interno del repo è presente una .gitattributes core.eoldirettiva .

Con Git 2.8+ (marzo 2016) , controlla se ci sono ancora trasformazioni eol con:

git ls-files --eol

2
NON USARE autocrlfOGGI! unsetted autocrlfè equivalente a false. Sei rimasto indietro rispetto ai movimenti alla moda in Git
Lazy Badger il

1
Come sopra, l'ho provato (anche se non con il flag globale) e non ha funzionato. la versione di git è 1.8.5.2.
imallett

@IanMallett "A questo punto, sembra che la macchina Linux abbia ancora CRLF": lo farà fino a quando non normalizzerai nuovamente il suo contenuto, o lo
clonerai

11

L'avevo capito. Sembra che il programma SCP stesse convertendo le terminazioni di riga. L'ho notato quando ho provato a creare deliberatamente un file con terminazioni LF e poi ho osservato che appariva come CRLF una volta scaricato.

Poiché questa era la soluzione per me, accetto questa risposta, ma le persone del futuro dovrebbero anche fare riferimento alle altre risposte per una soluzione più generale.


1
Buona cattura, più specifica della mia risposta. +1
VonC

4

Da gitattributes (5) Manuale pagina tema "Effetti"

text

Questo attributo abilita e controlla la normalizzazione di fine linea. Quando un file di testo viene normalizzato, le sue terminazioni di riga vengono convertite in LF nel repository. Per controllare quale stile di fine riga viene utilizzato nella directory di lavoro, utilizzare l' eolattributo per un singolo file e la core.eol variabile di configurazione per tutti i file di testo.

Set

L'impostazione dell'attributo di testo su un percorso abilita la normalizzazione di fine riga e contrassegna il percorso come file di testo. La conversione di fine riga avviene senza indovinare il tipo di contenuto.

Unset Il disinserimento dell'attributo text su un percorso dice a Git di non tentare alcuna conversione di fine riga al momento del checkin o del checkout.

core.autocrlfnella nuova (1.7.2+) Git non utilizzata core.eole impostazione corretta | disinserimento dell'attributo di testo considerato come modo più affidabile


Nel .gitattributesfile, avevo disabilitato esplicitamente tutto come testo, giusto? Inoltre, non lo vedo con un'opzione per non fare la conversione (anche se crlfpotrebbe non avere alcun effetto)?
imallett

6
Cosa importante che viene spesso confusa: per disattivare texte impedire qualsiasi conversione, è necessario impostare .gitattributes su * -text e non su * text=false. falsenon è un valore valido per l' textattributo - git non lo riconoscerà e tornerà invece alla sua impostazione predefinita di autocrlf. Inoltre, dopo aver modificato il textvalore, è necessario eseguire il backup di tutti i file dal repository locale, eseguire un commit, quindi ripristinare i file con la fine riga corretta in base alle esigenze e ripristinarli. Quindi il tuo fine riga non verrà più modificato da git.
JustAMartin
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.