Forza LF eol in repository git e copia di lavoro


170

Ho un repository git ospitato su github. Molti dei file sono stati inizialmente sviluppati su Windows e non sono stato troppo attento alle terminazioni di linea. Quando ho eseguito il commit iniziale, non avevo nessuna configurazione git in atto per imporre la terminazione di riga corretta. Il risultato è che ho un numero di file con terminazioni di linea CRLF nel mio repository github.

Ora sto sviluppando parzialmente su Linux e mi piacerebbe ripulire le terminazioni di linea. Come posso assicurarmi che i file siano archiviati correttamente con LF su github e che abbiano LF nella mia copia di lavoro?

Ho impostato un .gitattributesfile contenente text eol=LF; è corretto? Con quello impegnato e spinto, posso solo il rmmio repository locale e ri-clonare da Github per ottenere l'effetto desiderato?




Nessuno di questi è proprio quello che sto chiedendo. Sono l'unico sviluppatore e sono abbastanza disposto a configurare tutte le mie macchine allo stesso modo. Ho un repository esistente con alcuni file CRLF già impegnati e un paio di cloni su macchine diverse. Come posso aggiornare il repository e ogni copia funzionante, in modo che ci siano LF ovunque?
Chowlett,

Hai guardato questa guida di Github?
Andy,

Risposte:


237

Senza un po 'di informazioni su quali file sono nel tuo repository (codice sorgente puro, immagini, file eseguibili, ...), è un po' difficile rispondere alla domanda :)

Inoltre, considererò che sei disposto a impostare LF come terminazioni di riga nella tua directory di lavoro perché sei disposto ad assicurarti che i file di testo abbiano terminazioni di riga LF nel tuo repository .git se lavori su Windows o Linux . Anzi meglio prevenire che curare ....

Tuttavia, esiste un'alternativa migliore: approfitta delle terminazioni di linea LF nel tuo workdir Linux, le terminazioni di linea CRLF nel tuo workdir di Windows E le terminazioni di linea LF nel tuo repository.

Dato che stai lavorando parzialmente su Linux e Windows, assicurati che core.eolsia impostato nativee core.autocrlfimpostato su true.

Quindi, sostituire il contenuto del .gitattributesfile con il seguente

* text=auto

Ciò consentirà a Git di gestire la conversione dei finali di linea automagic per te, su commit e checkout. I file binari non verranno modificati, i file rilevati come file di testo vedranno le terminazioni di riga convertite al volo.

Tuttavia, poiché conosci il contenuto del tuo repository, puoi dare una mano a Git e aiutarlo a rilevare file di testo da file binari.

Se lavori su un progetto di elaborazione delle immagini basato su C, sostituisci il contenuto del tuo .gitattributesfile con il seguente

* text=auto
*.txt text
*.c text
*.h text
*.jpg binary

In questo modo i file con estensione c, h o txt verranno archiviati con i finali di riga LF nel repository e con i finali di riga nativi nella directory di lavoro. I file jpeg non verranno toccati. Tutti gli altri trarranno beneficio dallo stesso filtro automagico di cui sopra.

Per ottenere una comprensione più approfondita dei dettagli interiori di tutto questo, ti suggerisco di immergerti in questo ottimo post "Mind the end of the line" di Tim Clem, un Githubber.

Come esempio nel mondo reale, puoi anche dare un'occhiata a questo commit in cui .gitattributesvengono dimostrate le modifiche a un file.

AGGIORNA alla risposta considerando il seguente commento

In realtà non voglio CRLF nelle mie directory di Windows, perché il mio ambiente Linux è in realtà un VirtualBox che condivide la directory di Windows

Ha senso. Grazie per il chiarimento. In questo specifico contesto, il.gitattributes file da solo non sarà sufficiente.

Esegui i seguenti comandi sul tuo repository

$ git config core.eol lf
$ git config core.autocrlf input

Poiché il repository è condiviso tra l'ambiente Linux e Windows, questo aggiornerà il file di configurazione locale per entrambi gli ambienti. core.eolfarà in modo che i file di testo riportino i finali di riga LF sui checkout. core.autocrlfassicurerà il potenziale CRLF nei file di testo (risultante ad esempio da un'operazione di copia / incolla) venga convertito in LF nel repository.

Opzionalmente, si può contribuire a Git distinguere ciò che è un file di testo con la creazione di un .gitattributesfile contenente qualcosa di simile al seguente:

# Autodetect text files
* text=auto

# ...Unless the name matches the following
# overriding patterns

# Definitively text files 
*.txt text
*.c text
*.h text

# Ensure those won't be messed up with
*.jpg binary
*.data binary

Se hai deciso di creare un .gitattributesfile, esegui il commit .

Infine, assicurati di git statusmenzionare "niente da impegnare (directory di lavoro pulita)" , quindi eseguire la seguente operazione

$ git checkout-index --force --all

Ciò ricrea i file nella directory di lavoro, tenendo conto delle modifiche alla configurazione e del file .gitattributes file e sostituendo qualsiasi potenziale CRLF trascurato nei file di testo.

Una volta fatto ciò, ogni file di testo nella directory di lavoro git statusconterrà le terminazioni di riga LF e dovrebbe comunque considerare il workdir come pulito.


34
In realtà non voglio CRLF nelle mie directory di Windows, perché il mio ambiente Linux è in realtà un VirtualBox che condivide la directory di Windows; e mentre Notepad ++ ecc. può gestire solo LF su Windows, viè meno soddisfatto di CRLF. Voglio solo cambiarlo in modo che core.autocrlfsia false(o input)?
Chowlett,

5
Risposta eccellente. Una breve nota per chiunque utilizzi questa configurazione: La riga "* text = auto" dovrebbe essere la prima riga nel tuo file .gitattributes in modo che le righe successive possano sovrascrivere tale impostazione.
Ari Patrick,

9
@CMCDragonkai A seconda della shell, git checkout-index --force --allpotrebbe funzionare meglio. Il secondo punto sembra un po 'fuori tema rispetto alla domanda originale. Che ne dici di fare una domanda dedicata?
nulltoken

8
Non capisco perché .gitattributes non sia in grado di gestire il caso di condividere una copia funzionante tra Linux e Windows. Non possiamo impostare texte eol=lfottenere lo stesso risultato descritto nella tua risposta tramite core.eole core.autocrlf?
DanielSank,

10
git checkout-index --force --allnon fa niente per me. Ciò che funziona è l' elenco dei comandi nelle istruzioni di GitHub per affrontare questo problema.
Roman Starkov,

127

A partire da git 2.10 (rilasciato il 09-09-2016), non è necessario enumerare ogni file di testo separatamente. Git 2.10 risolto il comportamento di text = auto insieme a eol = lf . Fonte .

.gitattributes file nella radice del repository git:

* text=auto eol=lf

Aggiungi e impegnalo.

Successivamente, puoi seguire i passaggi e ora tutti i file sono normalizzati:

git rm --cached -r .  # Remove every file from git's index.
git reset --hard      # Rewrite git's index to pick up all the new line endings.

Fonte: risposta di Kenorb .


7
Git 2.10 è stato rilasciato il 3 settembre 2016.
stil

Ho eseguito questo e ha bloccato tutti i miei file non di testo
Anthony

È possibile impostare esplicitamente la modalità binaria su determinati file. - Mi chiedo perché il rilevamento automatico sia (ancora ?!) rotto su alcuni file
koppor

Questa dovrebbe essere la risposta accettata.
CletusW

25

Per forzare le terminazioni di riga LF per tutti i file di testo, è possibile creare il .gitattributesfile al livello superiore del repository con le seguenti righe (modificare come desiderato):

# Ensure all C and PHP files use LF.
*.c         eol=lf
*.php       eol=lf

che assicura che tutti i file che Git considera file di testo abbiano normalizzati ( LF) terminazioni di riga nel repository (normalmente core.eolcontrolla la configurazione di cui disponi per impostazione predefinita).

Sulla base delle nuove impostazioni degli attributi, tutti i file di testo contenenti CRLF dovrebbero essere normalizzati da Git. Se ciò non accade automaticamente, è possibile aggiornare manualmente un repository dopo aver modificato le terminazioni di riga, in modo da poter eseguire nuovamente la scansione e il commit della directory di lavoro procedendo come segue (indicata come directory di lavoro pulita):

$ echo "* text=auto" >> .gitattributes
$ rm .git/index     # Remove the index to force Git to
$ git reset         # re-scan the working directory
$ git status        # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"

o secondo i documenti GitHub :

git add . -u
git commit -m "Saving files before refreshing line endings"
git rm --cached -r . # Remove every file from Git's index.
git reset --hard # Rewrite the Git index to pick up all the new line endings.
git add . # Add all your changed files back, and prepare them for a commit.
git commit -m "Normalize all the line endings" # Commit the changes to your repository.

Vedi anche: post di @Charles Bailey .

Inoltre, se desideri escludere qualsiasi file per non essere trattato come un testo, disattiva il suo attributo di testo, ad es

manual.pdf      -text

O contrassegnalo esplicitamente come binario:

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary

Per vedere alcuni file di normalizzazione git più avanzati, controlla .gitattributessu Drupal core :

# Drupal git normalization
# @see https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
# @see https://www.drupal.org/node/1542048

# Normally these settings would be done with macro attributes for improved
# readability and easier maintenance. However macros can only be defined at the
# repository root directory. Drupal avoids making any assumptions about where it
# is installed.

# Define text file attributes.
# - Treat them as text.
# - Ensure no CRLF line-endings, neither on checkout nor on checkin.
# - Detect whitespace errors.
#   - Exposed by default in `git diff --color` on the CLI.
#   - Validate with `git diff --check`.
#   - Deny applying with `git apply --whitespace=error-all`.
#   - Fix automatically with `git apply --whitespace=fix`.

*.config  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.css     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.dist    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.engine  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.html    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=html
*.inc     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.install text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.js      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.json    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.lock    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.map     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.md      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.module  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.php     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.po      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.profile text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.script  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.sh      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.sql     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.svg     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.theme   text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.twig    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.txt     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.xml     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.yml     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2

# Define binary file attributes.
# - Do not treat them as text.
# - Include binary diff in patches instead of "binary files differ."
*.eot     -text diff
*.exe     -text diff
*.gif     -text diff
*.gz      -text diff
*.ico     -text diff
*.jpeg    -text diff
*.jpg     -text diff
*.otf     -text diff
*.phar    -text diff
*.png     -text diff
*.svgz    -text diff
*.ttf     -text diff
*.woff    -text diff
*.woff2   -text diff

Guarda anche:


2
1. text=autoè fuorviante. Non puoi usare text=autoe eolinsieme. L'impostazione eoldisabilita il rilevamento automatico dei file di testo. Questo è il motivo per cui devi specificare tutti quei tipi di file. Se autofosse abilitato, non avresti bisogno di tutto ciò. 2. Non hai bisogno texte eol=lf. eol=lfimposta efficacemente text.
Ben

2
Secondo ciò che ha detto @Ben, questa configurazione è attualmente errata e pericolosa se non si contrassegna esplicitamente tutti i file binari.
Michael R,

1
Ho letto che * text=auto eol=lfil primo text=autoviene ignorato da eol=lf. Dove hai trovato questa funzione? Ecco la mia fonte: stackoverflow.com/questions/29435156/...
CMCDragonkai

Rimosso * text=auto eol=lfdall'esempio, poiché è stato rimosso anche da Drupal. Valuta anche di rimuovere i commenti.
Kenorb,

4
È importante notare che ciò che @Ben ha detto non è più vero ed è sempre stato un bug, non un comportamento previsto.
Semmel,
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.