Quando lo si fa git diff
, dice "Nessuna nuova riga alla fine del file" .
Ok, non c'è newline alla fine del file. Qual è il grosso problema?
Qual è il significato del messaggio e cosa sta cercando di dirci?
Quando lo si fa git diff
, dice "Nessuna nuova riga alla fine del file" .
Ok, non c'è newline alla fine del file. Qual è il grosso problema?
Qual è il significato del messaggio e cosa sta cercando di dirci?
Risposte:
Indica che non si dispone di una nuova riga (in genere '\n'
, ovvero CR o CRLF) alla fine del file.
Cioè, semplicemente parlando, l'ultimo byte (o byte se sei su Windows) nel file non è una nuova riga.
Il messaggio viene visualizzato perché altrimenti non è possibile distinguere tra un file in cui è presente una riga alla fine e uno in cui non lo è. Diff deve comunque generare una nuova riga, altrimenti il risultato sarebbe più difficile da leggere o elaborare automaticamente.
Si noti che è un buon stile inserire sempre la nuova riga come ultimo carattere se è consentito dal formato del file. Inoltre, ad esempio, per i file di intestazione C e C ++ è richiesto dallo standard linguistico.
Non è solo un cattivo stile, può portare a comportamenti imprevisti quando si utilizzano altri strumenti nel file.
Ecco qui test.txt
:
first line
second line
Non vi è alcun carattere di nuova riga sull'ultima riga. Vediamo quante righe ci sono nel file:
$ wc -l test.txt
1 test.txt
Forse è quello che vuoi, ma nella maggior parte dei casi probabilmente ti aspetteresti che ci siano 2 righe nel file.
Inoltre, se si desidera combinare i file, potrebbe non comportarsi come previsto:
$ cat test.txt test.txt
first line
second linefirst line
second line
Infine, renderebbe i tuoi diff leggermente più rumorosi se dovessi aggiungere una nuova linea. Se hai aggiunto una terza riga, mostrerebbe una modifica alla seconda riga e alla nuova aggiunta.
L'unica ragione è che Unix storicamente aveva una convenzione di tutti i file di testo leggibili dall'uomo che terminavano con una nuova riga. Al momento, ciò evitava un'ulteriore elaborazione durante la visualizzazione o l'unione di file di testo ed evitava di trattare i file di testo in modo diverso rispetto ai file contenenti altri tipi di dati (ad es. Dati binari grezzi che non sono leggibili dall'uomo).
A causa di questa convenzione, molti strumenti di quell'epoca si aspettano la fine della nuova riga, inclusi editor di testo, strumenti di diffing e altri strumenti di elaborazione del testo. Mac OS X è stato costruito su BSD Unix e Linux è stato sviluppato per essere compatibile con Unix, quindi entrambi i sistemi operativi hanno ereditato la stessa convenzione, comportamento e strumenti.
Windows non è stato sviluppato per essere compatibile con Unix, quindi non ha la stessa convenzione e la maggior parte dei software Windows gestirà bene senza alcuna nuova riga finale.
Ma dal momento che Git è stato sviluppato per Linux per primo, e molti software open source sono basati su sistemi compatibili con Unix come Linux, Mac OS X, FreeBSD, ecc., La maggior parte delle comunità open source e i loro strumenti (compresi i linguaggi di programmazione) continuano seguire queste convenzioni.
Ci sono ragioni tecniche che avevano senso nel 1971, ma in questa era è principalmente convenzione e mantenimento della compatibilità con gli strumenti esistenti.
Se aggiungi una nuova riga di testo alla fine del file esistente che non ha già una newline character
alla fine, il diff mostrerà la vecchia ultima riga come modificata, anche se concettualmente non lo era.
Questo è almeno un buon motivo per aggiungere un newline character
alla fine.
Un file contiene:
A() {
// do something
}
hexdump:
00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20 A() {. // do
00000010: 736f 6d65 7468 696e 670a 7d something.}
Ora lo modifichi in
A() {
// do something
}
// Useful comment
hexdump:
00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20 A() {. // do
00000010: 736f 6d65 7468 696e 670a 7d0a 2f2f 2055 something.}.// U
00000020: 7365 6675 6c20 636f 6d6d 656e 742e 0a seful comment..
Il diff git mostrerà:
-}
\ No newline at end of file
+}
+// Useful comment.
In altre parole, mostra una differenza maggiore di quanto si sia verificato concettualmente. Mostra che hai eliminato la linea }
e aggiunta la linea }\n
. Questo è, in effetti, ciò che è accaduto, ma non è ciò che è accaduto concettualmente , quindi può essere fonte di confusione.
Il motivo per cui questa convenzione è entrata in pratica è perché nei sistemi operativi simili a UNIX un carattere di nuova riga viene trattato come terminatore di linea e / o limite di messaggio (questo include il piping tra processi, buffering di linea, ecc.).
Si consideri, ad esempio, che un file con solo un carattere di nuova riga viene trattato come una singola riga vuota. Al contrario, un file con una lunghezza di zero byte è in realtà un file vuoto con zero righe. Questo può essere confermato secondo il wc -l
comando.
Nel complesso, questo comportamento è ragionevole perché non ci sarebbe altro modo per distinguere tra un file di testo vuoto rispetto a un file di testo con una sola riga vuota se il \n
carattere fosse semplicemente un separatore di riga anziché un terminatore di riga. Pertanto, i file di testo validi devono sempre terminare con un carattere di nuova riga. L'unica eccezione è se il file di testo deve essere vuoto (nessuna riga).
C'è una cosa che non vedo nelle risposte precedenti. L'avvertimento di non chiudere la riga potrebbe essere un avvertimento quando una parte di un file è stata troncata. Potrebbe essere un sintomo di dati mancanti.
Il problema principale è ciò che si definisce linea e se la sequenza di caratteri end-on-line fa parte o meno della linea. Gli editor basati su UNIX (come VIM) o gli strumenti (come Git) usano la sequenza di caratteri EOL come terminatore di riga, quindi fa parte della riga. È simile all'uso del punto e virgola (;) in C e Pascal. In C il punto e virgola termina le istruzioni, in Pascal le separa.
Questo in realtà causa un problema perché le terminazioni di riga vengono automaticamente modificate dai file di sporco senza apportare modifiche. Vedi questo post per la risoluzione.
I file sorgente sono spesso concatenati da strumenti (C, C ++: file header, Javascript: bundlers). Se si omette il carattere di nuova riga, è possibile introdurre cattivi bug (in cui l'ultima riga di una sorgente è concatenata con la prima riga del file sorgente successivo). Si spera che tutti gli strumenti di concatenamento del codice sorgente inseriscano comunque una nuova riga tra i file concatenati, ma ciò non sembra sempre essere il caso.
Il punto cruciale del problema è che nella maggior parte delle lingue le newline hanno un significato semantico e end-of-file non è un'alternativa definita nella lingua per il carattere newline. Quindi dovresti terminare ogni affermazione / espressione con un carattere di nuova riga, incluso l'ultimo.
//
commento stile nel mezzo del codice.
Il tuo file originale probabilmente non aveva un carattere di nuova riga.
Tuttavia, alcuni editor come gedit in linux aggiungono silenziosamente newline alla fine del file. Non è possibile eliminare questo messaggio mentre si utilizza questo tipo di editor.
Quello che ho provato a superare questo problema è aprire il file con l'editor di codice di Visual Studio
Questo editor mostra chiaramente l'ultima riga e puoi eliminare la riga come desideri.
Per quello che vale, l'ho riscontrato quando ho creato un progetto IntelliJ su un Mac, quindi ho spostato il progetto sul mio computer Windows. Ho dovuto aprire manualmente ogni file e modificare l'impostazione di codifica in basso a destra nella finestra di IntelliJ. Probabilmente non succederà alla maggior parte se qualcuno leggesse questa domanda, ma ciò avrebbe potuto salvarmi un paio d'ore di lavoro ...