mirror of
https://github.com/go-gitea/gitea.git
synced 2026-03-11 17:46:29 -05:00
Gitea file view showing wrong amount of lines for both Unix and Windows/DOS line breaks but differently #11758
Open
opened 2025-11-02 09:46:50 -06:00 by GiteaMirror
·
28 comments
No Branch/Tag Specified
main
release/v1.25
release/v1.24
release/v1.23
release/v1.22
release/v1.21
release/v1.20
release/v1.19
release/v1.18
release/v1.17
release/v1.16
release/v1.15
release/v1.14
release/v1.13
release/v1.12
release/v1.11
release/v1.10
release/v1.9
release/v1.8
v1.25.3
v1.25.2
v1.25.1
v1.25.0
v1.24.7
v1.25.0-rc0
v1.26.0-dev
v1.24.6
v1.24.5
v1.24.4
v1.24.3
v1.24.2
v1.24.1
v1.24.0
v1.23.8
v1.24.0-rc0
v1.25.0-dev
v1.23.7
v1.23.6
v1.23.5
v1.23.4
v1.23.3
v1.23.2
v1.23.1
v1.23.0
v1.23.0-rc0
v1.24.0-dev
v1.22.6
v1.22.5
v1.22.4
v1.22.3
v1.22.2
v1.22.1
v1.22.0
v1.23.0-dev
v1.22.0-rc1
v1.21.11
v1.22.0-rc0
v1.21.10
v1.21.9
v1.21.8
v1.21.7
v1.21.6
v1.21.5
v1.21.4
v1.21.3
v1.21.2
v1.20.6
v1.21.1
v1.21.0
v1.21.0-rc2
v1.21.0-rc1
v1.20.5
v1.22.0-dev
v1.21.0-rc0
v1.20.4
v1.20.3
v1.20.2
v1.20.1
v1.20.0
v1.19.4
v1.21.0-dev
v1.20.0-rc2
v1.20.0-rc1
v1.20.0-rc0
v1.19.3
v1.19.2
v1.19.1
v1.19.0
v1.19.0-rc1
v1.20.0-dev
v1.19.0-rc0
v1.18.5
v1.18.4
v1.18.3
v1.18.2
v1.18.1
v1.18.0
v1.17.4
v1.18.0-rc1
v1.19.0-dev
v1.18.0-rc0
v1.17.3
v1.17.2
v1.17.1
v1.17.0
v1.17.0-rc2
v1.16.9
v1.17.0-rc1
v1.18.0-dev
v1.16.8
v1.16.7
v1.16.6
v1.16.5
v1.16.4
v1.16.3
v1.16.2
v1.16.1
v1.16.0
v1.15.11
v1.17.0-dev
v1.16.0-rc1
v1.15.10
v1.15.9
v1.15.8
v1.15.7
v1.15.6
v1.15.5
v1.15.4
v1.15.3
v1.15.2
v1.15.1
v1.14.7
v1.15.0
v1.15.0-rc3
v1.14.6
v1.15.0-rc2
v1.14.5
v1.16.0-dev
v1.15.0-rc1
v1.14.4
v1.14.3
v1.14.2
v1.14.1
v1.14.0
v1.13.7
v1.14.0-rc2
v1.13.6
v1.13.5
v1.14.0-rc1
v1.15.0-dev
v1.13.4
v1.13.3
v1.13.2
v1.13.1
v1.13.0
v1.12.6
v1.13.0-rc2
v1.14.0-dev
v1.13.0-rc1
v1.12.5
v1.12.4
v1.12.3
v1.12.2
v1.12.1
v1.11.8
v1.12.0
v1.11.7
v1.12.0-rc2
v1.11.6
v1.12.0-rc1
v1.13.0-dev
v1.11.5
v1.11.4
v1.11.3
v1.10.6
v1.12.0-dev
v1.11.2
v1.10.5
v1.11.1
v1.10.4
v1.11.0
v1.11.0-rc2
v1.10.3
v1.11.0-rc1
v1.10.2
v1.10.1
v1.10.0
v1.9.6
v1.9.5
v1.10.0-rc2
v1.11.0-dev
v1.10.0-rc1
v1.9.4
v1.9.3
v1.9.2
v1.9.1
v1.9.0
v1.9.0-rc2
v1.10.0-dev
v1.9.0-rc1
v1.8.3
v1.8.2
v1.8.1
v1.8.0
v1.8.0-rc3
v1.7.6
v1.8.0-rc2
v1.7.5
v1.8.0-rc1
v1.9.0-dev
v1.7.4
v1.7.3
v1.7.2
v1.7.1
v1.7.0
v1.7.0-rc3
v1.6.4
v1.7.0-rc2
v1.6.3
v1.7.0-rc1
v1.7.0-dev
v1.6.2
v1.6.1
v1.6.0
v1.6.0-rc2
v1.5.3
v1.6.0-rc1
v1.6.0-dev
v1.5.2
v1.5.1
v1.5.0
v1.5.0-rc2
v1.5.0-rc1
v1.5.0-dev
v1.4.3
v1.4.2
v1.4.1
v1.4.0
v1.4.0-rc3
v1.4.0-rc2
v1.3.3
v1.4.0-rc1
v1.3.2
v1.3.1
v1.3.0
v1.3.0-rc2
v1.3.0-rc1
v1.2.3
v1.2.2
v1.2.1
v1.2.0
v1.2.0-rc3
v1.2.0-rc2
v1.1.4
v1.2.0-rc1
v1.1.3
v1.1.2
v1.1.1
v1.1.0
v1.0.2
v1.0.1
v1.0.0
v0.9.99
Labels
Clear labels
$20
$250
$50
$500
backport/done
💎 Bounty
docs-update-needed
good first issue
hacktoberfest
issue/bounty
issue/confirmed
issue/critical
issue/duplicate
issue/needs-feedback
issue/not-a-bug
issue/regression
issue/stale
issue/workaround
lgtm/need 2
modifies/api
modifies/translation
outdated/backport/v1.18
outdated/theme/markdown
outdated/theme/timetracker
performance/bigrepo
performance/cpu
performance/memory
performance/speed
pr/breaking
proposal/accepted
proposal/rejected
pr/wip
pull-request
reviewed/wontfix
💰 Rewarded
skip-changelog
status/blocked
topic/accessibility
topic/api
topic/authentication
topic/build
topic/code-linting
topic/commit-signing
topic/content-rendering
topic/deployment
topic/distribution
topic/federation
topic/gitea-actions
topic/issues
topic/lfs
topic/mobile
topic/moderation
topic/packages
topic/pr
topic/projects
topic/repo
topic/repo-migration
topic/security
topic/theme
topic/ui
topic/ui-interaction
topic/ux
topic/webhooks
topic/wiki
type/bug
type/deprecation
type/docs
type/enhancement
type/feature
type/miscellaneous
type/proposal
type/question
type/refactoring
type/summary
type/testing
type/upstream
Mirrored from GitHub Pull Request
No Label
Milestone
No items
No Milestone
Projects
Clear projects
No project
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: github-starred/gitea#11758
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @ell1e on GitHub (Oct 1, 2023).
Description
(I was occasionally abrasive in some comments, I apologize. 🌸 )
Gitea shows a wrong amount of lines for both Unix and Windows/DOS line breaks in the web UI in both edit and code view, and in a very different and inconsistently wrong manner.
https://try.gitea.io/blablablablab/BlaTest/src/branch/main/unix.c This file has one line. A unix
\nsemantically terminates the previous line, so if a file ends in\nthen that means no line is coming after. Code view shows 1 line 🆗 correctly, but the "Edit" button shows 2 lines 🚫 wrongly.The Unix line break file authoritatively shown by Unix file editor vim, clearly just one line:

https://try.gitea.io/blablablablab/BlaTest/src/branch/main/windows.c This file has three lines. A Windows/DOS
\r\nsemantically separates two lines, so if a file ends in\r\nthen that means a blank line is coming after. Code view shows 2 lines 🚫 wrongly, but the "Edit" button shows 3 lines 🆗 correctly.The Windows/DOS line break file authoritatively shown by Windows file editor notepad.exe, clearly three lines:

⚠️ Please note most Unix code editors get Windows/DOS line breaks wrong, including vim and the
wc -lcommand, which counts line breaks characters and not lines, so it doesn't give correct line counts for Windows/DOX files. Get the correct lines displayed reliably: always check Windows/DOS\r\nline break files with notepad.exe on Windows, and always check Unix\nline break files with vim on Linux to show the correct amount of lines there. Or check with a hex editor what's really going on per file.Gitea Version
1.22.0+dev-74-g4ab597f47
Can you reproduce the bug on the Gitea demo site?
Yes
Log Gist
No response
Screenshots
No response
Git Version
whatever is used on try.gitea.io
Operating System
whatever is used on try.gitea.io
How are you running Gitea?
it's on try.gitea.io
Database
None
@wxiaoguang commented on GitHub (Oct 1, 2023):
The behavior has been documented in code:
And see:
@ell1e commented on GitHub (Oct 1, 2023):
Well all I can say is that it's wrong on 1.22.0+dev-74-g4ab597f47, at the exact locations and with the exact files I described and also linked above. I suggest to click the links and see for yourself, that should show it very well.
(Note added later: I was occasionally abrasive in some comments, I apologize. 🌸 )
@wxiaoguang commented on GitHub (Oct 1, 2023):
According to the definition, it has two lines, the second line is an empty line.
According to the definition, it has three lines, the first line is empty, the third line is empty.
Everything is as expectation.
@wxiaoguang commented on GitHub (Oct 1, 2023):
The reason for using
2 linesbut not1 linefora\n:a(1 line) anda\n(2 lines) at the moment.1 linefora\n, you won't be able to know whether there is a trailing\n@ell1e commented on GitHub (Oct 1, 2023):
The hex dump you gave for the first file ends in 0x65 0x0A as you can see yourself, which is equivalent to an ending of
"e\n". There is no other line break in that hex dump. Therefore no, it's one line, ending in a Unix line terminator which is how Unix line terminators work. (I didn't make the rules.) So this file is 1 line. Edit: sorry, had the wrong number here at first.In your second hex dump, you can see two instances of 0x0d 0xDA, which is equivalent to
"\r\n". Two line separators, which splits the file into three lines, according to how Windows line separators work. So this file is 3 lines.It's how these files natively work on the respective systems. Therefore, either the code view, or the edit view, is wrong on both of these files in some circumstances, and the line count you posted for the first file is wrong as well. Also in your own screenshot, the third file shows as "3 lines", yet only 2 are shown in the listing below, which seems incorrect.
@wxiaoguang commented on GitHub (Oct 1, 2023):
\nin POSIX is equivalent to\r\nin Windows, they are all EOL.So if you can accept that the
windows.chas 3 lines, I think you could also accept that theunix.chas 2 lines.The rules are open. You could propose your rules and PRs to improve the behavior, if most people like, and the content
a/a\ncould be distinguished clearly.@ell1e commented on GitHub (Oct 1, 2023):
According to Unix file semantics, I'm pretty sure these are both considered 1 line. The first one would be an incorrectly unterminated single line, but nevertheless, these are both just 1 line. I think GitHub shows some sort of icon to the side if the terminator for Unix files is incorrectly missing.
(Note added later: I was occasionally abrasive in some comments, I apologize. 🌸 )
@wxiaoguang commented on GitHub (Oct 1, 2023):
That's also what I have proposed in https://github.com/go-gitea/gitea/pull/19967#issuecomment-1184115968 .
@ell1e commented on GitHub (Oct 1, 2023):
I showed the screenshot.
\non Linux is considered a line terminator, so no new line is considered to start after it, you can see this in vim.On Windows,
\r\nis considered a line separator, see in notepad.exe.It's just what some people making these systems decided on, so it's really not my fault.
@ell1e commented on GitHub (Oct 1, 2023):
Maybe this helps, in GNOME's gedit text editor on Linux it's easier to see that it also considers this file just 1 line. (The file ending in
\nas a Unix line terminator.) This is forunix.c.And Notepad.exe should be considered authoritative and hopefully easy to see on Windows as well that it has 3 lines for the
windows.cfile, here it is again:@wxiaoguang commented on GitHub (Oct 1, 2023):
I do not understand how "vim" / "gedit" / "notepad" could be considered as "standard". They just have their quirks.
Have you tried VSCode? As a developer, I like VSCode's behavior more:
@ell1e commented on GitHub (Oct 1, 2023):
VS Code is incorrect, which is why I showed the native, established editors for each respective platform. Most cross-platform editors (like VS Code) handle one of the two platforms incorrectly.
@wxiaoguang commented on GitHub (Oct 1, 2023):
Gitea is also designed for cross-platform. And personally I consider VSCode is right, vim is right, notepad is right, no one is incorrect, they just have their quirks.
Anyway, the problem is open, while personally I do think current approach is good enough. Feel free to propose new rules and PRs.
@ell1e commented on GitHub (Oct 1, 2023):
I did some quick mockups to show what I think the correct behavior would look like.
File view
unix.cfixed:Edit view
unix.cfixed:File view
windows.cfixed:Edit view
windows.cfixed (was already correct):@ell1e commented on GitHub (Oct 1, 2023):
Well, one last comment but in my opinion it's pretty telling: VS Code was created by Microsoft who primarily deal with windows, and surprise (or rather, not surprise) it shows the
\nnon-Windows files wrongly. VIM was created on Unix, and shows\r\nfiles wrong. In my opinion, the only rule that makes sense is to make it display what the native established editors and tools do, as found on the platform native to the line ending type.There is no other way to make it more consistent. You'll always find some special editors, especially the cross-platform ones that originated on a different platform, that will show some platform's file endings slightly incorrect. Simply because this is a pretty common bug.
I'm just trying to help out getting it fixed, I understand that a lot of programs get this wrong.
@wxiaoguang commented on GitHub (Oct 1, 2023):
That's not true. All modern editors have consistent behavior: treating "\n" or "\r\n" as EOL. They are the same.
VIM just has too many technical debts, it just doesn't want to change its behavior for handling "\r"
Have you considered about a file which contains both
\nand\r\n?It is consistent for modern editors treating "\r\n" and "\n" equivalently.
And have you tried the Linux world famous editor emacs?
@eeyrjmr commented on GitHub (Oct 1, 2023):
That standard behaviour when using git on windows is during the install is to select the option with the most compatibility
"Checkout Windows-Style, Commit Unix-Style line endings"
The moment you have cross-OS users committing to the same repository this is the PRIMARY option that windows users MUST select to keep the repository in a sane consistent state between users.
Can you confirm you have this set ( core.autocrlf = true )
@ell1e commented on GitHub (Oct 1, 2023):
You're not saying what EOL means, I suspect you mean line separator, so actually not EOL/end of line?
Beyond vim and GNOME Text editor, it's all the basic command line tools like
cat,wc -l, and so on that also all think that\nis a line terminator, not a separator, for Unix/Linux files. I feel like maybe the basic core tools have more weight. Emacs seems to have been based on a cross-platform one as well rather than one written originally for Unix primarily, so I feel like it doesn't count. Otherwise at least make it consistent, gitea file view violates that. Edit: shortened for brevity.@eeyrjmr this isn't really related, I think. Open the files in a hex editor for the byte contents.
@ell1e commented on GitHub (Oct 1, 2023):
After some more thinking, I guess I can see a point for going with a modern same interpretation.
@wxiaoguang commented on GitHub (Oct 1, 2023):
There is no standard in "basic core" either. You see:
There is no standard, no official rule.
According to various public information, emacs was initially designed for POSIX, the native tool.
Since there is no standard, then no violation.
@eeyrjmr commented on GitHub (Oct 1, 2023):
@ell1e it is related though as this is the correct mitigation.
The bare git repository (irrespective of the forge) must be consistent and that is why on windows gitforwin recommends (checkout windows, checkin unix) as this way the bare host, linux checkout and windows checkout all appear consistent.
There is no standard except at the OS level and thus it must be mitigated. Sure some editors will fluff this to appear "consistent" but it doesn't change what is at byte level
@ell1e commented on GitHub (Oct 1, 2023):
Why are you using
echo -n? That explicitly strips the last\nso that'll give you a wrong result.emacs was apparently based on the TECO editor which wasn't for primarily POSIX or Unix, if i'm not reading it wrong. Maybe it kept the different handling for compatibility, I wouldn't know.
@ell1e commented on GitHub (Oct 1, 2023):
After some searching I found that POSIX actually seems to define it, so there even is a standard:
https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206
That makes
"aejiaelira this file is a single line\n"1 line. Does this help? I hope thatwindows.cis 3 is undisputed.@ell1e commented on GitHub (Oct 1, 2023):
(Edit: sorry that was a too strong wording by me, and a misunderstanding on my side anyway. I was occasionally abrasive in some comments, I apologize. 🌸 )
I don't understand that. Gitea agreeing with itself how many files a line has is a too high bar? I'm confused.
@wxiaoguang commented on GitHub (Oct 2, 2023):
I do not think it is "wrong". It's just a normal file without last trailing
\n. I was just showing the real line-counting problem for "incomplete line". You can also have files likehello world\nnice dayordef test():\n print('test'), which do not have the last trailing EOL.And see below.
I wouldn't say this is a feasible standard for "line-counting display".
For example: for a file content which contains an "Incomplete Line", like this:
a\nb, the first line isa\n, the second incomplete line isb. Do you want to see "1 line" or "2 lines"?wc), I could only admit that's your choice, but not most editors' / users', neither by vim.The behavior for POSIX and Windows should be the same. Otherwise I do not see it useful for cross-platform, for example:
What if you have a file which contains both
\nand\r\n? Do you want to see it as a POSIX file or a Windows file.I believe they should have the same behavior: only consider the
\nor\r\nas line-separator. If people don't like the last empty line, then do not render it (see below).There is no "too high bar", I have explained above: so far so good, good enough, for most cases.
The Gitea's definition in code is:
empty: 0 lines; "a": one line; "a\n": two lines; "a\nb": two lines. So Gitea only considers the\n/\r\n(EOL) as line-separator: there are a line before it and a line after it. Then, the last\nstarts an empty new line. That's Gitea's definition (and that's also most modern editors' definition), it's clear enough.And why Gitea doesn't show the last empty line in UI: Gitea intentionally hides the last empty line when rendering the content because it makes most users happy and makes the UI better. So it won't render the last empty line for Windows files either.
Gitea only reports the existence of the last empty new line by "xxx lines" (one more line then rendered) at the moment, so users could still know whether there is an empty last line.
And yes, there are still some improvements to do, eg: use an icon mark to indicate the last "incomplete line", then Gitea could report the rendered lines as line-counter, then it will be more consistent.
@ell1e commented on GitHub (Oct 2, 2023):
This is where github shows the "missing line terminator" icon, I think (and both lines).
For a mixed file you'd probably also add an indicator of some kind, at the top of the file or something.
As for Gitea right now, it shows different line counts and lines, and even different lines in file view and editor, for the same file. No matter how many lines a file should have I think that's the worst of all worlds, personally.
@ell1e commented on GitHub (Oct 11, 2023):
After re-reading, I'm confused by the remark. POSIX basically says
a\nis 1, anda\nb\nis 2. It just doesn't say whata\nbis, and as you say yourself, most editors seem to agree it's 2. Where's the problem? (And Windows' Notepad.exe saysa\r\nb\r\nis 3, anda\r\nbis 2, also pretty clear.)@silverwind commented on GitHub (Mar 1, 2024):
I think this is a easy fix: Show the number of lines that are rendered, which also matches GitHub's line count. Trailing newlines are never counted, regardless whether they are LF or CRLF. So in JS code it would be
str.replace(/\r?\n$/g, '').split(/\r?\n/).length.