Podczas robienia git diff
napis „Brak nowej linii na końcu pliku” .
Ok, na końcu pliku nie ma nowego wiersza. O co tyle szumu?
Jakie znaczenie ma przesłanie i co próbuje nam powiedzieć?
Podczas robienia git diff
napis „Brak nowej linii na końcu pliku” .
Ok, na końcu pliku nie ma nowego wiersza. O co tyle szumu?
Jakie znaczenie ma przesłanie i co próbuje nam powiedzieć?
Odpowiedzi:
Wskazuje, że nie masz nowego wiersza (zwykle '\n'
aka CR lub CRLF) na końcu pliku.
To po prostu ostatni bajt (lub bajty w systemie Windows) w pliku nie jest znakiem nowej linii.
Komunikat jest wyświetlany, ponieważ w przeciwnym razie nie można odróżnić pliku, w którym na końcu znajduje się nowa linia, a gdzie nie ma. Diff i tak musi wypisać nowy wiersz, inaczej wynik będzie trudniejszy do odczytania lub przetworzenia automatycznie.
Zauważ, że dobrym stylem jest zawsze umieszczanie nowego wiersza jako ostatniego znaku, jeśli pozwala na to format pliku. Ponadto, na przykład, w przypadku plików nagłówkowych C i C ++ jest to wymagane przez standard językowy.
To nie tylko zły styl, może prowadzić do nieoczekiwanego zachowania podczas korzystania z innych narzędzi w pliku.
Oto test.txt
:
first line
second line
W ostatnim wierszu nie ma znaku nowej linii. Zobaczmy, ile wierszy znajduje się w pliku:
$ wc -l test.txt
1 test.txt
Może właśnie tego chcesz, ale w większości przypadków prawdopodobnie spodziewałbyś się, że w pliku będą 2 linie.
Ponadto, jeśli chcesz połączyć pliki, może nie działać w oczekiwany sposób:
$ cat test.txt test.txt
first line
second linefirst line
second line
Wreszcie, spowodowałoby to, że twoje różnice byłyby nieco głośniejsze, gdybyś dodał nową linię. Jeśli dodasz trzeci wiersz, wyświetli się edycja drugiego wiersza, a także nowy dodatek.
Jedynym powodem jest to, że w Uniksie historycznie istniała konwencja wszystkich czytelnych dla ludzi plików tekstowych kończących się nową linią. W tym czasie unikano dodatkowego przetwarzania podczas wyświetlania lub dołączania plików tekstowych i unikano traktowania plików tekstowych inaczej niż plików zawierających inne rodzaje danych (np. Surowe dane binarne, które nie są czytelne dla człowieka).
Z powodu tej konwencji wiele narzędzi z tamtej epoki oczekuje końca nowej linii, w tym edytory tekstu, narzędzia różnicowania i inne narzędzia do przetwarzania tekstu. Mac OS X został zbudowany na BSD Unix, a Linux został opracowany tak, aby był kompatybilny z Unixem, więc oba systemy operacyjne odziedziczyły tę samą konwencję, zachowanie i narzędzia.
System Windows nie został opracowany pod kątem zgodności z systemem Unix, więc nie ma tej samej konwencji, a większość oprogramowania Windows poradzi sobie dobrze bez końca nowej linii.
Ale odkąd Git został opracowany najpierw dla Linuksa, a wiele programów typu open source jest zbudowanych na systemach kompatybilnych z Unixem, takich jak Linux, Mac OS X, FreeBSD itp., Większość społeczności open source i ich narzędzia (w tym języki programowania) nadal trwają przestrzegać tych konwencji.
Istnieją powody techniczne, które miały sens w 1971 roku, ale w tej erze jest to głównie konwencja i utrzymanie zgodności z istniejącymi narzędziami.
Jeśli dodasz nową linię tekstu na końcu istniejącego pliku, który nie ma jeszcze newline character
na końcu, diff pokaże starą ostatnią linię jako zmodyfikowaną, nawet jeśli koncepcyjnie tak nie było.
Jest to co najmniej jeden dobry powód, aby dodać newline character
na końcu.
Plik zawiera:
A() {
// do something
}
Hexdump:
00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20 A() {. // do
00000010: 736f 6d65 7468 696e 670a 7d something.}
Teraz go edytujesz
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..
Git diff pokaże:
-}
\ No newline at end of file
+}
+// Useful comment.
Innymi słowy, pokazuje większą różnicę niż występowała koncepcyjnie. To pokazuje, że usunąłeś linię }
i dodałeś ją }\n
. W rzeczywistości tak się stało, ale nie jest to koncepcyjne , więc może być mylące.
Powodem, dla którego ta konwencja weszła w życie, jest to, że w systemach operacyjnych typu UNIX znak nowej linii jest traktowany jako terminator linii i / lub granica komunikatów (obejmuje to przesyłanie potokowe między procesami, buforowanie linii itp.).
Rozważmy na przykład, że plik zawierający tylko znak nowej linii jest traktowany jako pojedynczy pusty wiersz. I odwrotnie, plik o długości zero bajtów jest w rzeczywistości pustym plikiem z zerowymi liniami. Można to potwierdzić zgodnie zwc -l
poleceniem.
W sumie takie zachowanie jest uzasadnione, ponieważ nie byłoby innego sposobu rozróżnienia pustego pliku tekstowego od pliku tekstowego z pojedynczą pustą linią, gdyby \n
znak był jedynie separatorem linii, a nie zakończeniem linii. Dlatego prawidłowe pliki tekstowe powinny zawsze kończyć się znakiem nowej linii. Jedynym wyjątkiem jest sytuacja, gdy plik tekstowy ma być pusty (bez wierszy).
Jest jedna rzecz, której nie widzę w poprzednich odpowiedziach. Ostrzeżenie o braku końca linii może być ostrzeżeniem, gdy część pliku zostanie obcięta. Może to być objaw braku danych.
Podstawowym problemem jest to, co definiujesz linię i czy sekwencja znaków end-on-line jest częścią linii, czy nie. Edytory oparte na UNIX (takie jak VIM) lub narzędzia (takie jak Git) używają sekwencji znaków EOL jako terminatora linii, dlatego jest to część linii. Jest podobny do używania średnika (;) w C i Pascalu. W C średnik kończy instrukcje, w Pascal oddziela je.
To faktycznie powoduje problem, ponieważ zakończenia linii są automatycznie modyfikowane, usuwając pliki bez wprowadzania w nich żadnych zmian. Zobacz ten post w celu rozwiązania.
Pliki źródłowe są często łączone przez narzędzia (C, C ++: pliki nagłówkowe, Javascript: programy pakujące). Jeśli pominiesz znak nowej linii, możesz wprowadzić nieprzyjemne błędy (gdzie ostatnia linia jednego źródła jest połączona z pierwszą linią następnego pliku źródłowego). Mam nadzieję, że wszystkie narzędzia konkatacji kodu źródłowego wstawiają nowy wiersz między połączonymi plikami, ale nie zawsze tak jest.
Sedno problemu polega na tym, że - w większości języków znaki nowej linii mają znaczenie semantyczne, a koniec pliku nie jest zdefiniowaną w języku alternatywą dla znaku nowej linii. Więc powinieneś zakończyć każde wyrażenie / wyrażenie znakiem nowej linii - łącznie z ostatnim.
//
komentarz styl w środku kodu.
Twój oryginalny plik prawdopodobnie nie miał znaku nowej linii.
Jednak niektóre edytory, takie jak gedit w systemie Linux, po cichu dodają nową linię na końcu pliku. Nie możesz pozbyć się tej wiadomości podczas korzystania z tego rodzaju edytorów.
Próbowałem przezwyciężyć ten problem, aby otworzyć plik za pomocą edytora kodu Visual Studio
Ten edytor wyraźnie pokazuje ostatni wiersz i możesz go usunąć, jak chcesz.
O ile warto, napotkałem to, gdy utworzyłem projekt IntelliJ na komputerze Mac, a następnie przeniosłem projekt na moją maszynę z systemem Windows. Musiałem ręcznie otworzyć każdy plik i zmienić ustawienie kodowania w prawym dolnym rogu okna IntelliJ. Prawdopodobnie nie zdarzyło się to większości, jeśli ktokolwiek czytał to pytanie, ale to mogło zaoszczędzić mi kilka godzin pracy ...