Diff options
authorBryce Kwon <bryce@brycekwon.com>
committerBryce Kwon <bryce@brycekwon.com>
commit
parent
tree
download
Rename CHANGELOG.txt to CHANGE.txt
Diffstat (limited to 'CHANGELOG.txt')
-rw-r--r--CHANGELOG.txt798
1 file changed, 0 insertions, 798 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
deleted file mode 100644
index c14bf3d..0000000
--- a/CHANGELOG.txt
+++ /dev/null
@@ -1,798 +0,0 @@
-cgit - Changelog
-================
-
-Notable changes to this fork, newest release first. History before v2.0.0
-belongs to upstream cgit and is not covered here.
-
-
-v2.9.2 (2026-10-25)
--------------------
-
-A polish release for narrow screens and for the finer details of the pages,
-with the summary's columns lined up, a login that says when it failed and a
-signed tag's signature folded away.
-
-Added
-.....
-
-* A wrong username or password brings the login form back with a message
- saying so, where it used to come back empty. Both auth filters carry it, an
- unknown user is told the same as a wrong password, and the button now sits
- under the fields. The README names the hooks, form.login and p.login-error.
-* A signed tag's signature, PGP, SSH or X.509, is folded away under the tag's
- message in details.signature, rather than printed as part of the message.
-* The syntax highlighter colours CSS properties and pseudo-classes, which
- Scintillua's css lexer tags with names it had no colour for.
-* Links, rows and buttons fade between colours, and the line highlight fades
- in, unless the reader asks for reduced motion.
-
-Changed
-.......
-
-* On a narrow window the tabs stay on one row and scroll sideways with the
- active tab in view, rather than wrapping a tab or two onto a second row.
-* On a narrow screen each commit detail sits under its label, and a phone
- leaves out the diffstat's file modes. The summary keeps its log counts on a
- phone, so its rows still line up.
-* List rows highlight under a mouse only, so on a touch screen the last row
- tapped no longer stays highlighted.
-* The logo is brighter in dark mode.
-* The diffstat bars are drawn as SVG, so a strict Content Security Policy no
- longer has to allow inline styles, and the diffstat box has room inside its
- border.
-
-Fixed
-.....
-
-* The summary's sections disagreed on how many columns its table had. With
- the default config the log and clone rows stopped short of the table's edge,
- on a phone the log rows did with any config, and the summary and refs pages
- were invalid HTML.
-* A commit's branch and tag labels were joined to the last word of its subject,
- so a narrow cell broke the line before that word and stranded another.
-* A download link and its signature could break across lines mid-name.
-* The rule above the code on the blob and blame pages, and the line highlight,
- ended at the longest line of a short file rather than at the page's edge.
-* A commit that changes no files drew an empty diffstat frame.
-
-
-v2.9.1 (2026-10-24)
--------------------
-
-A bugfix release for the tree and blame pages, whose line numbers had drifted
-away from the code since v2.0.0 in Safari and in every browser on a typical
-Linux desktop, until the code sat dozens of lines below its number at the end
-of a long file.
-
-Added
-.....
-
-* A character a browser would start a new line at, though git does not, is
- shown as an escape sequence in span.escape on the tree and blame pages and
- by the syntax highlighter: a carriage return with no line feed after it, a
- vertical tab, a form feed, next line and the Unicode line and paragraph
- separators.
-
-Changed
-.......
-
-* Patches end with the cgit version again, written as git writes its own, so
- this release signs them "cgit 2.9.1". The footer and the generator tag still
- carry no version.
-
-Fixed
-.....
-
-* The code beside the line numbers was set in the browser's own monospace
- font, which made each of its lines a little taller than its number, by a
- pixel in Safari and on Linux, so the two columns drifted apart down every
- file.
-* A lone carriage return started an extra line in every browser, and U+2028
- and U+2029 did in Safari, each pushing every later line below its number.
-* The line highlight sat a pixel low, covered only the digits of each number,
- and ended at the edge of the view on a file scrolled sideways.
-* Code in a readme took the browser's own monospace font, Courier in Chrome
- and Safari, rather than the theme's --font-mono.
-
-
-v2.9.0 (2026-10-17)
--------------------
-
-A compatibility and hardening release. Lua 5.5 is supported, readmes render
-closer to how GitHub shows them, the auth examples were overhauled, 32-bit
-builds compile again, and two audits of the extensions and of the C code
-closed what they found, from a cache lock that an exec filter let go of to
-a log search that was never the literal match it claimed to be.
-
-Added
-.....
-
-* Lua 5.5, detected when building and claimed by every extension, which
- needs luaossl 20260910 or later there.
-* Stable markup hooks for site themes: a data-page attribute, named sections
- and a class per link kind.
-* Readmes follow GitHub more closely: relative links lead into the tree at
- the readme's own ref, lines of a paragraph run together, a table may cut a
- paragraph short, a wrapped list item stays in its list, urls and addresses
- in angle brackets link, backslash escapes and character references are
- honoured, underscores inside words are left alone, and headings get the
- anchors GitHub gives them. Images and badges are left out.
-* The auth examples bind a session to the account's password hash, so a
- changed password ends it, use a __Host- cookie where one can be set, turn
- down passwords past 256 bytes unchecked, spend a missing account's login on
- a real hash, load their libraries only when a request needs one, and say
- which hash kinds each system's crypt checks.
-* Avatars are looked up by SHA-256, offered at twice the size to dense
- screens, marked decorative, and left out when luaossl is missing.
-* The syntax highlighter finds a script's lexer from its shebang line.
-* make get-git checks the Git tarball against the SHA-256 kernel.org lists.
-* The dumb transport answers HEAD from the ref store and the index dates a
- repository from its reftable, so reftable repositories clone and age.
-
-Changed
-.......
-
-* enable-trailers is now enable-commit-trailers.
-* The bundled Git is 2.56.0.
-* The pages carry no version number, and the Lua-less build is checked by
- the suite as well.
-* Any path below the about page answers 404, the about filter is handed the
- tree url its links need, and the about redirect keeps the query string.
-* The dumb transport serves only what a clone asks for, a loose object, a
- pack with its index and info/http-alternates, sends each file with its
- size and keeps none of them in the cache.
-* A page behind an auth filter is marked private, and every page that
- follows a branch takes cache-dynamic-ttl.
-* summary-branches, summary-tags and max-ref-count read a negative value as
- no limit, and the feed refuses pathspec magic as the log does.
-* patch, rawdiff and signature downloads hold to max-blob-size, and a
- readme past it says so on the about page.
-* Diffs no longer ask xdiff for a minimal result, which cost quadratic time
- on a reordered file, and tar.xz snapshots are compressed on one thread.
-* The cache slot lock is an flock, which outlasts an exec filter's swap of
- stdout where the record lock did not.
-* Git is built without translations or Tcl, the release script builds with
- the compiler it probed, the two builds no longer share vendor/git at once,
- sparse checks the sources as gnu17, and a musl build is documented.
-* The example tracker links in link-commits.lua and link-trailers.lua ship
- commented out, so an unedited copy links object names alone.
-* The manual, README and sample cgitrc say what the code does: every page
- and query parameter, every file make install puts in place, the defaults
- and value syntax, and which filters get the repository variables.
-
-Fixed
-.....
-
-* 32-bit builds, where Git 2.55's size_t object sizes no longer compiled.
-* The log search matched as a regular expression after all, so a term with
- a bracket in it answered a 500 and a crafted one took the memory of the
- box.
-* A pushed date or zone outside what git's date code accepts, and a notes
- ref pointing at anything but a tree, ended the summary, refs, log, commit
- and feed pages of the repository.
-* A snapshot name led to a branch spelled like the tag's stem, members
- of a snapshot named by its suffix alone started at a slash, and a missing
- PATH refused every compressed snapshot.
-* The plain view answered twice for duplicate tree entries and read a freed
- mimetype on the way, a control byte in a file name made the web server
- refuse the download, a scanned defbranch could name a path outside the
- repository, and the error page resolved the very id it had refused.
-* A fill whose last flush failed to write, on a full disk for one, left the
- visitor a blank response, a cache ttl in the tens of millions of minutes
- overflowed, and an empty list reached qsort as a null, which glibc's
- sanitizer build aborted on.
-* Links built from the repository url and the feed link's branch were not
- encoded, a readme vanished behind an annotated tag, a followed log lost
- its root commit and paged by the wrong name, a Lua build crashed when git
- wrote before cgit's own setup, text was cut inside a multibyte character,
- and the tag page offered snapshots of trees and blobs.
-* An absolute symlink target was linked as a path inside the tree, a chain
- of single directories ended in a dangling separator, a repository without
- a path was dated from a file named "(null)", a NUL ended a config comment
- early, and a tree row was left open when a link target could not be read.
-* An empty repo.url is ignored, a readme ending in a colon is gated like a
- path on disk, an error mid capture keeps its message, date-format=
- local-local renders, an indented comment in the mimetype file is skipped,
- types that only spell xml get no charset, the sendfile loop stops at a
- short slot, slot keys and pages are read and written in full, and the
- stats page stops after its error page.
-* auth-file.lua refuses every repository when it cannot read its repos file,
- cookie, readme and avatar parsing run in linear time, the cache hook keeps
- its rm errors from pushers, the age hook leaves its directory writable to
- the group, a Lua script may write while it loads, and every Lua filter
- failure is named in the log.
-* Git read the global config for its trace settings before cgit isolated
- the environment, so every request probed $HOME/.gitconfig, which the
- home-access test caught only once it ran on a real x86_64 kernel.
-* make DEVELOPER=1 passes: string literals sit behind const pointers and
- callbacks are passed by address.
-
-
-v2.8.0 (2026-09-16)
--------------------
-
-A feature and hardening release. Commit trailers get a table of their own, the
-mailmap is applied everywhere a person is named, the per-repository filter gate
-gives way to a trust switch for scanned repositories, and an audit closed every
-crash and every request that could reach git unchecked.
-
-Added
-.....
-
-* Commit trailers shown as a table under the message, behind enable-trailers.
-* trailer-filter, with link-trailers.lua linking Fixes, Reverts, Closes, Bug and
- bare URLs.
-* The .mailmap at HEAD applied to every ident and search, behind enable-mailmap.
-
-Changed
-.......
-
-* enable-filter-overrides became trust-scan-config, gating only the risky keys a
- scanned repository's own cgitrc or git config can set.
-* A request may name a revision only by hex id or ref name, and the log search
- matches literally.
-* A die inside git answers a 500 page and logs the reason.
-* The static ttl covers only the pages whose content the id fixes.
-* One phrase and status for a bad object id or a revision that is not a commit.
-* A scan path that is itself a repository is named after its directory.
-* The tag page shows the tagged object's full id.
-
-Fixed
-.....
-
-* Crashes on a repository without a path, an unknown page name, an empty url, a
- repo.* key after scan-path, a broken git config in a scanned repository, an
- unparsable commit and a history with a missing parent object.
-* A full cache disk no longer fails every cacheable request, and an error mid
- page finishes the page instead of starting a second response.
-* Revisions, paths and snapshot names can no longer reach git as options,
- pathspec magic or archive members outside the extraction directory.
-* Filters answer one error page when they cannot run, start with SIGPIPE at its
- default and no longer leave a page half written when they exit early.
-* Limits hold for a diff limited to a directory, a large symlink target and a
- deep chain of single directories.
-* The about page no longer serves the repository's own files beside a readme on
- disk.
-* Snapshots of dash-named tags, a missing compressor, nested tags, dumb clones
- of an empty repository, a symlink cycle under the scan path, the fallback
- default branch, a blank line in mimetype-file and a POST body arriving in
- pieces all answer correctly.
-* Commit encoding, trailer splitting, notes lookup, subject truncation, ref
- decorations and statistics buckets render correctly in their edge cases.
-* Two builds of the same sources are byte for byte identical.
-
-
-v2.7.1 (2026-09-08)
--------------------
-
-A bugfix release. A tag's snapshot names no longer depend on how git happens to
-store its ref.
-
-Fixed
-.....
-
-* Snapshot names shed a tag's leading v reliably again. On a case-insensitive
- filesystem a freshly created tag kept the v until git packed the refs, so the
- same tag could change its snapshot names over time.
-
-
-v2.7.0 (2026-09-08)
--------------------
-
-A configuration release. The badly named keys are renamed, the statistics switch
-folds back into max-stats, the parser now reports what it ignores, and the theme
-toggle is gone.
-
-Added
-.....
-
-* Unknown or misplaced configuration keys are reported to stderr instead of
- being dropped silently.
-
-Changed
-.......
-
-* noheader became enable-header, with its polarity flipped.
-* noplainemail became enable-plain-email, with its polarity flipped.
-* cache-root-ttl became cache-index-ttl.
-* cache-repo-ttl became cache-summary-ttl.
-* cache-scanrc-ttl became cache-scan-ttl.
-* agefile became age-file.
-* renamelimit became rename-limit.
-* repo.extra-head-content became repo.head-content.
-* Old key spellings are not read and draw the unknown-key warning.
-* max-stats enables the statistics page and bounds its coarsest period again, as
- it did before v2.2.0.
-* enable-stats and repo.enable-stats are gone.
-* repo.max-stats=0 turns the statistics page off for one repository.
-
-Removed
-.......
-
-* The header theme toggle. The light and dark theme follows the system
- preference alone, and a saved choice in localStorage is no longer read.
-* Selects no longer submit their form the moment they change. The diff and stats
- panels always show their reload button instead of keeping it for readers
- without scripting.
-
-Fixed
-.....
-
-* A lua filter that fails now answers with an error page naming the script and
- the error, where before the page was fed back into the broken filter and the
- visitor got an empty response.
-
-
-v2.6.1 (2026-09-01)
--------------------
-
-A small release. Every clone row is now a link a browser can follow, and the
-diffstat graph drops the output's last inline style, so a strict
-Content-Security-Policy needs no exceptions.
-
-Changed
-.......
-
-* Clone rows are links. The ssh, scp and git forms cannot be followed by a
- browser, so those rows point at the first http url in the clone list, or at
- the repository page when there is none, and the scp form stays out of the
- document head since it is not a URI.
-* The diffstat bars take their width from colspan on a fixed-layout table rather
- than from inline styles. A site pointing css= at a stylesheet of its own needs
- the new inner graph table rule from cgit.css, or the bars render as equal
- width segments spaced apart.
-
-
-v2.6.0 (2026-08-28)
--------------------
-
-A cleanup release. Output is ASCII only and deterministic, the statistics page
-drops its language breakdown, and two bugs a cross-compiler review found are
-fixed.
-
-Added
-.....
-
-* README.txt documents how cgit urls are built, both url forms, every query
- parameter, the endpoints that are not pages, and worked examples.
-* tests/README.txt describes the suite layout, numbering and traps.
-* Pages carry a meta description, from the repository or root description.
-* Submodule links resolve through .gitmodules, and submodule rows are set apart
- in the tree listing.
-
-Changed
-.......
-
-* Output is ASCII only. The truncation marker is an ellipsis, the title path
- separator is plain, and unrepresentable bytes print as a question mark.
-* Non-breaking space padding is done with CSS.
-* Pages are byte for byte deterministic. The footer drops its clock and an empty
- atom feed is dated at the epoch.
-* The charset is spelled UTF-8 everywhere.
-* Snapshots use registered media types, so application/gzip, application/zip and
- application/zstd replace their x- forms.
-* Status lines use the standard HTTP reason phrases.
-* Table header and image attributes follow the usual order.
-* Test scripts are renumbered into themed ranges and prefer POSIX forms.
-
-Removed
-.......
-
-* The statistics page no longer breaks the tree down by language. The built-in
- extension table was a standing maintenance cost, classifying by extension
- misleads, and the tree walk it needed was the only part of the page reading
- object sizes. The commits-per-author table is unchanged.
-
-Fixed
-.....
-
-* The statistics page no longer reads past its argument list when given a path.
- The array handed to git's revision setup lacked a trailing null, so a url such
- as /repo/stats/dir read whatever followed it on the stack.
-* A detached head stays selected in the branch switcher. Browsing at a raw
- commit or tag left it resting on the first branch, so switch moved away.
-
-
-v2.5.0 (2026-08-23)
--------------------
-
-A correctness and conformance release. The generated markup moves fully to
-HTML5, cgit stops emitting HTTP headers a front-end server should own, the page
-cache and repository scan get real locking, and pages pinned to a commit now say
-so.
-
-Added
-.....
-
-* Pages pinned to a commit via the id parameter show it. The branch switcher
- gains a "(detached)" entry, the page title carries the short hash, and the
- path strip gains a rev crumb linking back to the branch tip.
-* The shipped server configs gain Permissions-Policy, cross-origin isolation
- headers and form-action in the CSP, and enable HSTS. The nginx config adds
- catch-all blocks that drop requests for hostnames the site does not serve,
- since cgit keys its cache on Host.
-* Operators get log lines for two previously silent failures, a cache too small
- for its keys and a repository scan lock that fails for reasons other than
- contention.
-* The documentation now spells out that the cache directory must be pre-created,
- owned by the web server account and mode 0700.
-* Login forms carry autocomplete hints for password managers, and avatar images
- load lazily.
-
-Changed
-.......
-
-* Atom feeds conform to the RFC. They are served as application/atom+xml with an
- XML declaration, invalid bytes are replaced instead of emitted, and every
- entry carries an author name.
-* Dates render as HTML time elements with strict ISO 8601 values.
-* Markup is fully HTML5. Complete documents everywhere, real table header cells,
- no XHTML self-closing slashes and no HTML comments in the output. The plain
- directory listing gets a doctype so browsers leave quirks mode.
-* cgit no longer sends Last-Modified, Expires or ETag. Front-end caching policy
- lives in the server configs, which now append headers rather than replace
- cgit's own.
-* Only a full object id qualifies for cache-static-ttl, since the id parameter
- accepts any rev git can resolve.
-* Percentages in the diffstat bars and language table print from integers, so a
- filter that switches the numeric locale cannot corrupt the output.
-* URL encoding is tightened. Ampersands and plus signs are percent-encoded in
- paths, and query strings are escaped at each sink instead of being
- pre-escaped.
-* The responsive breakpoints only hide or restack chrome and never change font
- sizes or gutters. Narrow screens drop the search box, branch switcher and
- author columns, and diff tables scroll inside their own box.
-* The client-side age refresher uses the same bucket arithmetic as the server,
- so refreshed ages no longer drift from rendered ones.
-* The example agefile hook was renamed to post-receive.cgit-age.
-
-Removed
-.......
-
-* The repository homepage feature, including repo.homepage, the gitweb.homepage
- mapping and the homepage tab.
-* The post-update.update-server-info example hook.
-
-Fixed
-.....
-
-* Error pages are no longer cached, so requesting a commit before it is pushed
- can no longer pin a 404 into the cache forever.
-* An abandoned cache fill no longer appends a second page to the response,
- publishes its lock file or leaves a stale copy to be served.
-* A crashed repository scan no longer freezes the index forever. Scan and cache
- locks are fcntl locks released by the kernel with the process, and lock
- holders re-verify their lock file after acquiring it, closing a race that
- could truncate a live file.
-* Blobs containing a NUL byte anywhere are treated as binary in tree and blame
- views, and the raw path substitutes replacement characters instead of
- truncating at the NUL.
-* An annotated tag whose tagger has no email no longer passes NULL to the email
- filter, repositories without an owner no longer render an empty link,
- single-page logs drop the pager, and filler rows use correct colspan values.
-* The dev preview server splits CGI headers at the earliest blank line, so DOS
- line endings in page output no longer swallow the document head.
-
-
-v2.4.0 (2026-08-08)
--------------------
-
-A performance and robustness release. Output is buffered instead of written
-fragment by fragment, the hot paths shed repeated work, and a cluster of fixes
-closes crashes reachable from repository-controlled content.
-
-Changed
-.......
-
-* The bundled Git is updated from 2.54.0 to 2.55.0, with NO_RUST set so Cargo
- does not become a silent build requirement.
-* Page output is collected in a 64 KB buffer and written in whole blocks instead
- of one write per HTML fragment.
-* Blame and tree line numbers, hex dump rows and intra-line diff highlights are
- emitted in batches rather than per line or character.
-* The diff view renders each file while it is already open and replays it after
- the diffstat, replacing a second full tree walk.
-* Blame reuses a commit's rendered detail across its entries, the index resolves
- repository ages once before sorting, and the stats page computes its period
- labels once.
-* Side-by-side tab expansion is a single pass, where it was previously quadratic
- on tab-heavy lines.
-* Search queries are clamped to 512 characters, bounding the matching work one
- request can demand and the size of cache keys.
-* The sources compile as gnu17 so their meaning does not drift with compiler
- defaults, and the release script probes each hardening flag, preferring
- FORTIFY_SOURCE level 3.
-
-Fixed
-.....
-
-* A repository under scan-path could supply its own module-link template, which
- was handed straight to printf. Surplus conversions could crash cgit or read
- stack memory into the page. Templates are now expanded manually.
-* Sorting branches by age crashed when a branch ref pointed at a tag or tree
- object.
-* Hunks whose header omits a length, as git writes for single-line hunks, were
- numbered from zero in side-by-side diffs and lost their links.
-* A request whose cache key was too long to read back could never hit,
- regenerating the page every time while still writing an unusable slot. Such
- requests now skip the cache and log it.
-* Git config isolation ran from a constructor attribute that some compilers
- silently discard. It now runs from main.
-* A memory leak of deferred side-by-side lines and an integer-truncation bug in
- the stats author ordering.
-
-
-v2.3.0 (2026-08-05)
--------------------
-
-A consolidation release focused on how the project is laid out, deployed and
-operated. Everything an operator ships or edits now lives under custom/, the
-server configs became complete standalone files, and the hooks and auth filters
-were hardened.
-
-Added
-.....
-
-* New enable-relative-dates option, default 1. Set to 0 to always show calendar
- dates in the age columns instead of elapsed times.
-* New date-format option controlling those calendar dates, accepting git's date
- format names plus strftime formats.
-* New example hook post-receive.cgit-cache that clears cgit's output cache after
- a push, so new commits appear immediately instead of after the cache TTL.
-* New CGIT_EXTRA_CFLAGS make variable applying extra compiler flags to cgit's
- own objects only, not the bundled git.
-
-Changed
-.......
-
-* The tree was reorganized. The git submodule moved to vendor/git, and the
- example cgitrc, Lua filters, hooks and server configs moved into custom/.
- Operators following old paths must update them.
-* Repositories with no commits get a dedicated page with working clone URLs
- instead of a bare notice with dead tabs.
-* A description file still holding git's "Unnamed repository" boilerplate is
- treated as no description.
-* The theme is applied before first paint, so pages no longer flash the wrong
- theme, and the header no longer shifts as the page loads.
-* The nginx, Apache and lighttpd configs are complete, runnable files carrying
- their own top-level directives, rather than snippets assuming a distro base.
-* The agefile hook uses committer dates from branches only, writes atomically
- and keeps its output readable by the web server. The update-server-info hook
- likewise forces a safe umask.
-* The auth filters' secret moved from /var/cache/cgit to /var/lib/cgit, so
- pruning the cache no longer invalidates every live session.
-* The dev preview server forwards cookies, referers and request bodies, so the
- auth filters can be exercised locally, and decodes escaped repository names.
-
-Removed
-.......
-
-* The built-in help page and its enable-help option.
-* GitHub Actions CI, the release workflow and the make dist target.
-
-Fixed
-.....
-
-* Ordinary working trees found by scan-path are listed as repo instead of
- repo/.git.
-* The auth filters match cookie names containing pattern magic characters, and
- auth-file tolerates a users file saved with CRLF line endings.
-
-
-v2.2.0 (2026-07-25)
--------------------
-
-A hardening release that puts explicit ceilings on the work a single request can
-provoke, reworks the statistics page, and overhauls the bundled Lua filters.
-
-Added
-.....
-
-* The stats page gains a language breakdown, sizing the tree at HEAD by file
- extension without ever loading blob contents.
-* New enable-stats option, default 0, as the dedicated switch for the statistics
- page.
-* New max-patch-count option, default 50, bounding how many commits the patch
- view emits as a series.
-* New about-filter script about-render.lua, a server-side renderer for markdown,
- man pages and plain text, falling back to escaped text when its dependencies
- are missing.
-* New make dist target staging the release tarball, so local and released
- tarballs are identical.
-
-Changed
-.......
-
-* max-stats no longer enables the stats page, it only bounds the coarsest
- period. Instances relying on it must now also set enable-stats=1.
-* The auth filters are hardened. Cookies are Secure by default, redirect targets
- are validated so a login cannot bounce to another origin, password checks are
- constant time even for unknown users, and a protected repository with no
- resolvable users denies everyone.
-* The avatar filters skip missing addresses instead of hashing garbage,
- normalise the rest, and expose size, style and URL settings.
-* link-commits.lua takes a user-editable list of pattern and URL rules instead
- of a hardcoded issue reference, resolving all matches in one pass.
-* The syntax highlighter falls back through an extension map when lexer
- detection fails and emits its plain-text fallback in slices instead of one
- full-size copy.
-* The masthead reserves the logo column so the header no longer shifts while the
- logo loads, and the logo and favicon were redrawn at higher resolution.
-
-Removed
-.......
-
-* The client-side markdown renderer and the enable-markdown option. Rendered
- readmes now require about-filter pointed at about-render.lua.
-* The PDF documentation targets.
-
-Fixed
-.....
-
-* A file name containing a quote could break out of the link attributes in
- side-by-side diffs. Paths are now percent-encoded.
-* A commit with no message no longer crashes the history views.
-* max-blob-size also bounds the diff path, so a huge blob is reported as binary
- instead of inflated into memory, and dangling refs are skipped instead of
- dereferenced.
-* The diff size caps are no longer silently disabled when follow is active.
-* The header branch switcher respects max-ref-count instead of emitting an
- option per branch on every page.
-* zstd snapshots run single-threaded, so one request cannot fan out across every
- core.
-* The stats walk is pruned by date instead of visiting all history, and a commit
- whose date cannot be represented is dropped rather than indexing a month table
- out of bounds.
-* The cache listing bounds its key output, and a malformed cgitrc line no longer
- discards the rest of the file.
-* The build no longer triggers a section-alignment warning on every macOS link.
-
-
-v2.1.0 (2026-07-19)
--------------------
-
-A release about behaving well on large repositories and under a strict
-Content-Security-Policy. Syntax highlighting moves out of the browser and into
-an optional server-side filter.
-
-Added
-.....
-
-* New max-ref-count option, default 200, capping how many branches and tags each
- refs section lists, with independent pagination on the dedicated branch and
- tag pages.
-* New max-diff-files option, default 200. A commit touching more files renders
- only its diffstat, with a notice pointing at the per-file diffs and the patch
- view.
-* New max-diff-lines option, default 1000. A single file exceeding it within a
- whole-commit view links to its own diff page instead of rendering inline.
- Single-file diffs, rawdiff and patch are never capped.
-* An optional server-side syntax highlighter, syntax-highlight.lua, built on the
- Scintillua lexers with around 120 languages, degrading to plain escaped text
- when its dependencies are absent.
-* A built-in help page documenting the site's URL patterns, behind the new
- enable-help option. Removed again in v2.3.0.
-* URL fragments highlight the targeted source line in blob and blame views,
- support ranges like #n5-n12, and land the target mid-viewport.
-
-Changed
-.......
-
-* The auto-submitting select controls drop their inline onchange handlers and
- are wired up from cgit.js, so the option forms work under a CSP without
- unsafe-inline.
-* A plaintext readme keeps its line structure instead of collapsing into a
- run-on paragraph.
-* Syntax highlighting of source views moved from the browser to the optional
- filter. Without a source-filter, code is served plain, and the client-side
- highlighter is deleted.
-* Font sizes were evened out across the interface, and the external-link icon
- follows the tab's text color in both themes.
-* The mobile layout hides the author and size columns, the search form and the
- branch switcher, so nothing forces sideways scrolling.
-
-Removed
-.......
-
-* The owner-filter hook and its per-repository override. Owners always render as
- plain linked text.
-
-Fixed
-.....
-
-* Release binaries no longer ship with an empty version string when git describe
- fails in a shallow clone.
-
-
-v2.0.0 (2026-07-16)
--------------------
-
-First release of this fork, cut from upstream cgit v1.3.1. The page chrome is
-rebuilt as semantic HTML with dark mode and a phone layout, the runtime sheds
-its external interpreters and crypto libraries, and around two dozen security
-and correctness fixes land.
-
-Added
-.....
-
-* Built-in client-side syntax highlighting in cgit.js for roughly 33 languages,
- used when no source-filter is configured.
-* Built-in client-side markdown rendering for about pages behind the new
- enable-markdown option, restricted to safe link and image targets.
-* A light and dark theme with a toggle cycling auto, light and dark, persisted
- in localStorage and invisible without JavaScript.
-* A responsive layout for phones and small screens, with stacking panels and a
- repository index that collapses to name and age.
-* New enable-tree-group-dirs option listing directories before files in the tree
- view.
-* New enable-cache-list option, default 0, gating the previously unprotected
- cache listing page.
-* A fully commented example cgitrc listing every option at its default, and
- complete nginx, Apache and lighttpd examples with security headers.
-* An example post-update hook running update-server-info, needed because the
- built-in clone support speaks dumb HTTP.
-* tools/serve.py, a dependency-free local preview server, and
- tools/release-build.sh, a hardened Linux release build.
-* CI covering gcc and clang, the test suite under ASan and UBSan, sparse, and a
- hardened PIE build, plus a tag-triggered release workflow shipping hardened
- tarballs with checksums.
-* Accessible names on the search field, branch switcher and breadcrumb
- navigation, and contextual titles on the nav tabs.
-
-Changed
-.......
-
-* max-blob-size defaults to 10 MB instead of unlimited, and now caps everything
- cgit reads into memory to serve, including plain and blob output. Oversized
- objects return a 413 page.
-* section-sort defaults to 0, so the order repositories are written in cgitrc is
- respected rather than alphabetized.
-* Repository age on the index is derived from HEAD instead of a hardcoded
- refs/heads/master, so repositories on main show an age.
-* The page chrome is semantic HTML instead of nested tables, keeping the
- existing class and id names so custom themes still match.
-* The filter scripts moved to a Lua-only set. simple-authentication.lua became
- auth-inline.lua, file-authentication.lua became auth-file.lua and
- commit-links.sh became link-commits.lua.
-* Lua is optional and autodetected through pkg-config, preferring LuaJIT.
- NO_LUA=1 forces a self-contained binary.
-* The sources were reorganized into source/, libraries/, assets/, extensions/,
- examples/, tools/ and tests/, with all generated output under build/.
-* The auth filters compare cookie HMACs in constant time, set SameSite=Lax, and
- strip header injection from Set-Cookie and Location values.
-
-Removed
-.......
-
-* OpenSSL is no longer a build dependency, and libcurl is not required.
-* Every Python filter script, including the Pygments highlighter, the markdown
- and rst converters and the Python gravatar filter.
-* The Gentoo LDAP auth filter, owner-example.lua, about-formatting.sh and the
- man and txt about converters.
-* The unused name query parameter and the never-read cache-max-create-time and
- max-lock-attempts settings.
-
-Fixed
-.....
-
-* An unauthenticated arbitrary file write through the log id parameter, which
- reached git's revision parser as an option. Revisions beginning with a dash
- are rejected.
-* Cache poisoning through a spoofed Host header. The scheme and host are now
- part of the cache key.
-* Stored XSS from about pages, which were written as raw HTML when no
- about-filter was configured. They are now escaped.
-* Two path traversals, one past the about-path prefix check via a sibling
- directory sharing a name prefix, and one through a crafted HEAD ref.
-* max-blob-size is enforced before a blob is read into memory, not after.
-* A signed-comparison bypass of the authentication POST size limit, and an
- unbounded history walk from a crafted ofs value, now clamped.
-* Every snapshot was undecompressable whenever a global git config existed,
- because git's error output was compressed into the archive.
-* Numerous crashes, among them out-of-bounds accesses on short paths and empty
- URLs, NULL dereferences on odd blobs and authorless commits, a division by
- zero in the diffstat and undefined ctype behaviour on negative chars.
-* Truncated pages after stat-only diffs and binary blames, a 200 instead of a
- 404 for unknown blob paths, submodule hashes losing digits in diffs, pager
- links dropping search terms containing reserved characters, a missing updated
- element in empty atom feeds and negative ages from the age refresher.