Wat is de betekenis van het logboek “Geen nieuwe regel aan het einde van bestand”?

Als je een git diffdoet, staat er “Geen nieuwe regel aan het einde van het bestand”.

Wat is de betekenis van het bericht en wat probeert het ons te vertellen?


Antwoord 1, autoriteit 100%

Het geeft aan dat je geen nieuwe regel hebt (meestal '\n', ook wel CR of CRLF genoemd) aan het einde van het bestand.

Dat wil zeggen, eenvoudig gezegd, de laatste byte (of bytes als je Windows gebruikt) in het bestand is geen nieuwe regel.

Het bericht wordt weergegeven omdat er anders geen manier is om het verschil te zien tussen een bestand met een nieuwe regel aan het einde en een bestand waarin dat niet het geval is. Diff moet toch een nieuwe regel uitvoeren, anders zou het resultaat moeilijker te lezen of automatisch te verwerken zijn.

Merk op dat het een goede stijl is om de nieuwe regel altijd als laatste teken te plaatsen als het bestandsformaat dit toelaat. Verder is het bijvoorbeeld voor C- en C++-headerbestanden vereist door de taalstandaard.


Antwoord 2, autoriteit 23%

Het is niet alleen een slechte stijl, het kan ook leiden tot onverwacht gedrag bij het gebruik van andere tools in het bestand.

Hier is test.txt:

first line
second line

Er staat geen teken voor een nieuwe regel op de laatste regel. Laten we eens kijken hoeveel regels er in het bestand zitten:

$ wc -l test.txt
1 test.txt

Misschien is dat wat je wilt, maar in de meeste gevallen zou je verwachten dat er twee regels in het bestand staan.

Als je bestanden wilt combineren, gedraagt het zich mogelijk niet zoals je zou verwachten:

$ cat test.txt test.txt
first line
second linefirst line
second line

Ten slotte zou het je diffs iets luidruchtiger maken als je een nieuwe regel zou toevoegen. Als u een derde regel zou toevoegen, zou deze zowel een bewerking van de tweede regel als de nieuwe toevoeging tonen.


Antwoord 3, autoriteit 6%

De enige reden is dat Unix van oudsher een conventie had waarin alle door mensen leesbare tekstbestanden op een nieuwe regel eindigden. Op dat moment voorkwam dit extra verwerking bij het weergeven of samenvoegen van tekstbestanden, en werd voorkomen dat tekstbestanden anders werden behandeld dan bestanden die andere soorten gegevens bevatten (bijv. onbewerkte binaire gegevens die niet door mensen leesbaar zijn).

Vanwege deze conventie verwachten veel tools uit die tijd de eindigende nieuwe regel, inclusief teksteditors, diffing-tools en andere tekstverwerkingstools. Mac OS X is gebouwd op BSD Unix en Linux is ontwikkeld om Unix-compatibel te zijn, dus beide besturingssystemen hebben dezelfde conventie, hetzelfde gedrag en dezelfde tools geërfd.

Windows is niet ontwikkeld om Unix-compatibel te zijn, dus het heeft niet dezelfde conventie, en de meeste Windows-software zal prima werken zonder een achterblijvende nieuwe regel.

Maar aangezien Git eerst voor Linux werd ontwikkeld, en veel open-sourcesoftware is gebouwd op Unix-compatibele systemen zoals Linux, Mac OS X, FreeBSD, enz., zijn de meeste open-sourcegemeenschappen en hun tools (inclusief programmering talen) deze conventies blijven volgen.

Er waren technische redenen die in 1971 logisch waren, maar in dit tijdperk is het vooral conventie en het handhaven van compatibiliteit met bestaande tools.


Antwoord 4, autoriteit 6%

Als u een nieuwe regel teksttoevoegt aan het einde van het bestaande bestand dat nog geen newline characteraan het einde heeft, zal de diff de oude laatste regel als gewijzigd, hoewel dat conceptueel niet zo was.

Dit is in ieder geval een goede reden om aan het einde een newline charactertoe te voegen.

Voorbeeld

Een bestand bevat:

A() {
    // do something
}

Hexdump:

00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20  A() {.    // do 
00000010: 736f 6d65 7468 696e 670a 7d              something.}

Bewerk het nu met

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..

De Git Diff wordt weergegeven:

- }
\ No newline at end of file
+}
+// Useful comment.

Met andere woorden, het toont een grotere diff dan conceptueel opgetreden. Het laat zien dat u de lijn }verwijdert en de lijn }\nhebt toegevoegd. Dit is in feite wat er is gebeurd, maar het is niet wat Conceptueel is gebeurd, dus het kan verwarrend zijn.


Antwoord 5, Autoriteit 3%

Het betekent alleen dat het einde van het bestand een nieuwe regel heeft. Het is geen catastrofe. Het is gewoon een bericht om het duidelijker te maken dat er niet één is wanneer je naar een diff kijkt in de opdrachtregel.


Antwoord 6, Autoriteit 2%

De reden waarom deze conventie in de praktijk kwam, is omdat op Unix-achtige besturingssystemen een nieuwlijnteken wordt behandeld als een lijnterminator en / of een berichtgrens (dit omvat leidingen tussen processen, lijnbuffering, enz.).

Overweeg, bijvoorbeeld, dat een bestand met slechts een nieuwlijnkarakter wordt behandeld als een enkele, lege regel. Omgekeerd is een bestand met een lengte van nul bytes eigenlijk een leeg bestand met nullijnen. Dit kan worden bevestigd volgens de wc -l-opdracht.

In totaal is dit gedrag redelijk omdat er geen andere manier zou zijn om onderscheid te maken tussen een leeg tekstbestand versus een tekstbestand met een enkele lege regel als de \nkarakter slechts een lijnafscheider was in plaats van een line-terminator. Dus, geldige tekstbestanden moeten altijd eindigen met een nieuwlijnteken. De enige uitzondering is of het tekstbestand leeg is om leeg te zijn (geen regels).


Antwoord 7, Autoriteit 2%

Er is één ding dat ik niet zie in eerdere reacties. WAARSCHUWING OVER GEEN END-OF-LINE kan een waarschuwing zijn wanneer een gedeelte van een bestand is afgekapt. Het kan een symptoom zijn van ontbrekende gegevens.


Antwoord 8

Het kernprobleem is wat u de lijn definieert en of u eind-on-line
karaktervolgorde maakt deel uit van de regel of niet. Unix-gebaseerde redacteuren
(zoals vim) of gereedschappen (zoals GIT) Gebruik EOL-karaktervolgorde als
LINE TERMINATOR, daarom is het een deel van de lijn. Het is vergelijkbaar met
gebruik van puntkomma (;) in C en Pascal. In C-puntmijnolon eindigt
uitspraken, in Pascal scheidt het ze.


Antwoord 9

Dit veroorzaakt eigenlijk een probleem, omdat lijnuiteinden automatisch vuilbestanden worden gewijzigd zonder wijzigingen aan hen in te dienen. Zie dit bericht voor resolutie.

Git vervangen LF met CRLF


Antwoord 10

Bronbestanden zijn vaak samengevoegd door Tools (C, C++: Header-bestanden, JavaScript: bundlers). Als u het nieuwe lijnteken weglaat, kunt u vervelende bugs introduceren (waarbij de laatste regel van één bron is aangeconcerenteerd met de eerste regel van het volgende bronbestand). Hopelijk plaatsen alle hulpmiddelen voor de broncode daarin een nieuwe lijn tussen aangecatenateerde bestanden, maar dat lijkt niet altijd het geval te zijn.

De kern van het probleem is – in de meeste talen hebben nieuwe regels een semantische betekenis en is het einde van het bestand geen door de taal gedefinieerd alternatief voor het teken van de nieuwe regel. Dus je zou elke uitspraak/uitdrukking moeten beëindigen met een teken van een nieuwe regel — inclusief de laatste.


Antwoord 11

Uw originele bestand had waarschijnlijk geen teken voor een nieuwe regel.

Sommige editors, zoals geditin linux, voegen stilletjes een nieuwe regel toe aan het einde van het bestand. Je kunt dit bericht niet verwijderen als je dit soort editors gebruikt.

Ik heb geprobeerd dit probleem op te lossen door het bestand te openen met de visual studio code-editor

Deze editor toont duidelijk de laatste regel en u kunt de regel naar wens verwijderen.


Antwoord 12

Voor wat het waard is, ik kwam dit tegen toen ik een IntelliJ-project op een Mac maakte en het project vervolgens naar mijn Windows-computer verplaatste. Ik moest elk bestand handmatig openen en de coderingsinstelling rechtsonder in het IntelliJ-venster wijzigen. Waarschijnlijk gebeurt dit niet bij de meeste mensen die deze vraag lezen, maar dat had me een paar uur werk kunnen besparen…


Antwoord 13

ubuntu$> vi source.cpp
:set binary noeol

Other episodes