Skip to content

90% of the repo's packed content is one prebuilt V8 static archive, stored twice (93.4% of the working tree) #246

Description

@monkopedia-coder

Code-health suggestion (proactive — staged for your review)

Category: hygiene — repository weight

Where: samples/v8/libv8_monolith.a (tracked at HEAD), plus samples/v8/include/libv8_monolith.a
(same archive at its pre-#112 path, still in history)

90% of this public repo is a prebuilt third-party static library, in two copies

Two blobs, both reachable from origin/main:

$ git ls-tree -r -l HEAD | awk '{s+=$4} END {printf "%d bytes / %d files\n", s, NR}'
66806257 bytes / 546 files

$ git ls-tree -r -l HEAD | sort -k4 -nr | head -3
100644 blob 6170aa8f…  62396638  samples/v8/libv8_monolith.a
100644 blob 87b36a29…    285431  clangwalk/krapped/clangwalk.cc
100644 blob 2d294ced…    145685  krapper/.../codegen/KotlinWriter.kt

62,396,638 of 66,806,257 tracked bytes = 93.4% of the working tree, in one file. The
second-largest tracked file is 219× smaller.

Packed (what a clone actually downloads), over the blobs reachable from origin/main:

$ git rev-list origin/main --objects | awk '{print $1}' \
    | git cat-file --batch-check='%(objectsize:disk) %(objecttype)' \
    | awk '$2=="blob"{s+=$1;n++} END {printf "%d bytes across %d blobs\n", s, n}'
29052248 bytes across 2291 blobs

$ # the top two, by packed size, of those 2291:
14106228  6170aa8f…  samples/v8/libv8_monolith.a           (62396638 raw, at HEAD)
12082470  921760b3…  samples/v8/include/libv8_monolith.a   (55918284 raw, history only)
    88988  2cb8ed1b…  (the third-largest blob in the repo)

26,188,698 of 29,052,248 packed blob bytes = 90.1%, and the gap to the third-largest blob is 147×.
gh repo view Monkopedia/kplusplus reports diskUsage 28,542 KB, which agrees.

The second copy is the same archive at the path it had before
61273a5 cleanup: unify samples under samples/ (#112) moved it. Git stores both; the move did not
free the old one. It is not LFS — grep -c filter=lfs samples/v8/.gitattributes0, and the only
rule in that file is the *.bat CRLF line.

What it is, and what depends on it

It is a build output of a third-party project — V8's libv8_monolith.a, consumed by
samples/v8/build.gradle.kts:139 (library("libv8_monolith.a")). Nothing in the repo produces it,
nothing pins the V8 revision it came from, and it carries no provenance or licence note of its own
beyond the V8 headers checked in beside it.

samples/v8 is a standalone build: not in settings.gradle.kts, in no workflow, last touched
2026-07-27 (b787196, the #184 tool merge — a mechanical rename, not use). So every clone of this
public repo pays ~26 MB for a sample that no gate here builds.

Proposed — this one is a decision, not a mechanical fix

Three options, in increasing cost and effect. (a) is the only one that shrinks an existing clone,
and it is a history rewrite, which is why this is filed for your call rather than dispatched.

  • (a) Rewrite it out of history (git filter-repo --path samples/v8/libv8_monolith.a --path samples/v8/include/libv8_monolith.a --invert-paths) and have samples/v8/README document how to
    obtain or build the archive. Recovers ~26 MB of the 28 MB repo. Rewrites every commit SHA — every
    open PR, fork and local clone has to re-base, and the issue tracker's commit links go stale. Needs
    your explicit go-ahead.
  • (b) Git LFS for samples/v8/*.a. Keeps SHAs, but LFS objects still count against the account
    and a plain clone no longer yields a working sample — and history keeps both existing copies
    unless (a) is also done, so on its own it recovers nothing.
  • (c) Untrack it going forward (git rm --cached + .gitignore) and document the fetch step.
    Costs nothing, breaks nobody, and recovers zero bytes from history — it only stops the number
    growing when the archive is next refreshed. Honest floor, not a fix.

There is also a prior question that may make this moot: if samples/v8 is retired (it builds in
no workflow, and #231 already records that docs/ARCHITECTURE.md:64-72 and README.md:111-118 list
it while omitting samples/multiproject), then (a) becomes "delete the sample and rewrite the
archive out", which is one decision instead of two.

Why: this is the single largest thing in the repo by an order of magnitude, it is a third-party
binary with no provenance, and it is paid for by every clone of a public repository for a sample that
nothing here builds. It is also the kind of item that only gets cheaper to fix the earlier it is
decided — a rewrite gets more disruptive with every fork and open PR.

Effort: larger — (a) is irreversible and coordinated; (c) is mechanical but recovers nothing.

Refs #231, Refs #112.

Filed by the nightly code-health pass. To act on it: relabel agent-workable (it'll flow into triage→work). To decline: close it — it won't be suggested again.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    health-suggestionProactive code-health suggestion from the nightly analysis pass (staged for review)needs-decisionRequires user input on direction, scope, or design

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions