# Share an lcov / genhtml Coverage Report — The Whole Tree on One Link

Canonical: https://commareports.com/share-lcov-report
Published: 2026-08-25

> genhtml writes a directory of per-file HTML that only makes sense together. Publish the whole thing to Comma: one URL, source drill-down intact, comments on the uncovered lines.

# Share an lcov coverage report

`lcov` gives you a tracefile; `genhtml` turns it into the thing people
actually read:

```bash
lcov --capture --directory . --output-file coverage.info
lcov --remove coverage.info '/usr/*' --output-file coverage.info
genhtml coverage.info --output-directory coverage-html
```

What you get is `coverage-html/index.html`, a page per directory, a page
per source file with the hit counts in the gutter, and `gcov.css`. The
value is the drill-down — which is precisely what doesn't survive being
sent as an attachment.

## Publish the directory

Drag `coverage-html/` (or a zip of it) into
[the app](https://commareports.com/):

- `index.html` becomes the **report body**.
- Every per-file page and the stylesheet upload alongside, and the
  relative links between them are rewritten to the uploaded copies — so
  clicking through from the summary to `src/parser.c` still works.
- Nothing needs a local web server, which is the other reason these
  reports usually stay on one machine.

Same shape for JavaScript: `nyc report --reporter=lcov` writes
`coverage/lcov-report/`, and it publishes identically. For the Python
`coverage html` case, see
[sharing an htmlcov folder](/share-coverage-report).

## From CI

```bash
genhtml coverage.info --output-directory coverage-html

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html coverage-html/index.html \
        --arg title "Coverage — $GIT_COMMIT" '{title: $title, html: $html}')"
```

One report id per branch keeps one URL and appends a revision per run.
The interesting question about coverage is never the number, it's the
direction — and a revision history answers that without a dashboard
product. See [publishing from CI](/docs/ci).

## What review adds

- **Anchored threads** on an uncovered branch, in the source view —
  [commenting on HTML](/comment-on-html).
- **Revisions**, so "coverage dropped" is a diff rather than an
  assertion.
- **Access per report** — private, team, domain-gated or named
  reviewers. See the [sharing model](/docs/sharing).

## Limits

- **Entry HTML: 5 MB.** Assets: 25 MB per file, 250 MB and 500 files
  total. A large C++ tree can exceed 500 pages — `genhtml` on a
  subdirectory, or the `--prefix` and `--exclude` flags, keeps the
  published report to the part under review.
- **60 requests/minute per token.**

## Try it

Comma is free — unlimited reports, unlimited commenters, unlimited
revision history.

**[Publish a coverage report →](https://commareports.com/)**

### Related

- [Share an htmlcov coverage report](/share-coverage-report) · [Share a JaCoCo report](/share-jacoco-report)
- [Share a pytest report](/share-pytest-report) · [Share a Vitest report](/share-vitest-report)
- [Publish from CI](/docs/ci)
