githash home

How githash works

What it does

githash gives you per-file git blob hashes for any GitHub commit, and lets you pivot any file into VirusTotal by its raw SHA-256. Two hashes per file, two different jobs:

Using the search bar

One input does two jobs depending on what you paste:

GitHub repo
owner/repo, owner/repo@ref, or any https://github.com/… URL → ingests the commit and renders its file tree.
Git blob hash
6–40 hex chars → finds every ingested file with these exact bytes.

If a hex prefix uniquely resolves to one blob, the URL auto-extends to the full 40-char SHA so the link you share is unambiguous.

Swap github.com → githash.org

You don't have to copy a repo into the search bar at all. Take any GitHub repo URL in your address bar and change the host from github.com to githash.org — leave the rest of the path untouched. githash reads the path, ingests that exact commit, and renders the file tree:

github.com/octocat/Hello-World
        ↓  (just change the host)
githash.org/octocat/Hello-World

The same path forms GitHub uses all carry over, so whatever page you're looking at maps cleanly:

repo root
githash.org/owner/repo → the default branch (HEAD)
branch / tag
githash.org/owner/repo/tree/main → that ref, resolved to a commit
exact commit
githash.org/owner/repo/commit/<sha> → that immutable snapshot
release tag
githash.org/owner/repo/releases/tag/v1.0.0 → the tagged ref
pull request
githash.org/owner/repo/pull/42 → ingests every commit in the PR and ties the PR to them, with the author and any Actions runs
a single file
githash.org/owner/repo/blob/main/path/to/file → ingests the repo and opens that file's details panel

githash always ingests the whole repo at the given ref — a /blob/… URL just auto-opens the one file you pointed at. Tip: in the browser address bar you can edit only the github.com part and hit enter.

Once the page loads, githash rewrites the URL to a canonical hash route pinned to the resolved commit SHA (see how refs work), so the link you copy afterward won't drift.

Browsing a repo

The file tree mirrors the repo at the ingested commit. Folders collapse and expand. Click any file row to open its details panel:

Release artifacts

A GitHub release can ship uploaded files alongside the source — installers, binaries, packaged builds. These aren't part of the code tree, so they never show up in the file list. githash pulls them in separately and lists them in a releases panel below the tree.

Each artifact shows its SHA-256, size, download count, and a View on VirusTotal pivot — so you can vet a shipped binary the same way you'd vet any file in the repo.

⚠ Watch for artifacts that changed. If a file has been published under more than one SHA-256, githash flags it with a “distinct hashes over time” note. A download whose contents quietly changed — same name, same release — is worth a closer look before you trust it.

Artifact names aren't clickable on purpose — githash never points a click straight at a release binary. Use the hash or the VirusTotal link to inspect it instead.

Cross-repo dedup

Two files with identical bytes have identical git blob SHAs — that's git's content-addressing guarantee. githash keys on the blob SHA, so the same jQuery file dropped into 100 repos shows up as one blob entry with 100 occurrences. Click "Search Blob" on any file to see those occurrences (owner/repo, commit, path) and deep-link into each.

How refs work (and why it matters)

GitHub refs — branches and tags — are mutable pointers, not snapshots. The same v1.0.0 tag might point to a different commit today than it did last month. main moves every time someone pushes. HEAD tracks whatever the default branch happens to point at.

Commit SHAs, on the other hand, are immutable. A commit SHA is a cryptographic hash of the snapshot, so it can never quietly change meaning.

When you ingest owner/repo@v1.0.0, githash resolves the ref to a commit SHA at that exact moment and stores both. Every subsequent ingest re-resolves the ref and records what we see, preserving the ref's history of commits.

A ref that points somewhere different than last time is a meaningful signal. The file contents at v1.0.0 today are not what they were last week — the tag overlaps but the bytes diverge. Common causes:

Canonical links

After every ingest, githash rewrites the URL to use the resolved commit SHA, not the ref. Share that:

#/repo/octocat/Hello-World@7fd1a60b01f91b314f59955a4e4d4e80d8edf11d

Anyone opening it sees the exact same bytes you did. A link with @main drifts the next time someone pushes.

External and ghost commits

Every fork of a repo shares the same underlying storage on GitHub. A side effect of that: a commit pushed to someone's fork can be opened under the original repo's URL — and the page looks completely legitimate, repo name and all. It's a favorite trick for making sketchy code appear to belong to a project you trust.

githash checks whether a commit is actually part of the repo you're viewing. When it isn't, githash splits the verdict in two depending on whether the source is still findable in the fork network:

⚠ fork This commit isn't in this repo — it lives in a fork. The fork link is shown so you can verify what it actually contains. Common, mostly benign causes: contributor PR branches, release-bot branches (e.g. changeset-release/main), and in-flight feature work that hasn't merged.
⚠ ghost This commit isn't in this repo and no live source ref was found anywhere in the fork network. The source may have been deleted — either a benign cleanup or, in the worst case, an attacker covering their tracks after planting a CFOR phishing link. githash can't tell the two apart, but the URL is harder to verify either way.

For external commits with a live source, githash also snapshots the fork at ingest time so the file tree is preserved here even if the fork is later deleted. (The separate orphaned pill on individual commits is unrelated — that one means a commit was dropped from its ref by a non-fast-forward push.)

⚠ imposter commit (Actions) The same ghost trick gets used against GitHub Actions: an attacker pushes an orphan commit to a throwaway branch (e.g. oidc-61fff775), that commit adds and runs a malicious “release” workflow — executing with the repository's own publish/OIDC credentials — and then the branch is deleted. The run survives in the repo's Actions history, but the commit it ran is a ghost: in the repo's history nowhere, on no live ref anywhere. Because that run is keyed to a SHA nobody navigates to, a per-commit lookup never sees it — so githash sweeps the repo's recent runs, classifies each run's head the same way it classifies commits, and surfaces any imposter run in the Actions panel of every commit view, linked to the commit and the deleted branch it ran on.

The two hashes, explained

Every file has two fingerprints. They look alike but answer different questions — and mixing them up is the most common trip-up, so here's the plain version.

Git blob SHA — “is this the exact same file?”

The 40-character hash git uses to identify a file's contents. Two files with the same git blob SHA are byte-for-byte identical — that's how githash spots the same file showing up across different repos. It's the hash shown throughout the file tree, and the one the search bar matches when you paste a hash.

⚠ Don't paste this into VirusTotal. A git blob SHA isn't the hash VirusTotal uses, so it won't find your file there. For that, use the SHA-256 below — or just click View on VirusTotal on any file and githash sends the right one.

SHA-256 — “what do security tools call this file?”

The 64-character hash that VirusTotal and most security tools use to look up a file. GitHub doesn't provide it, so githash calculates it for you. The first time anyone needs a given file's SHA-256 there's a brief pause while it's computed; after that it's saved and instant for everyone.

Limits and gotchas

Privacy + data

githash only knows about public GitHub repos that someone has explicitly ingested through this tool. Nothing is crawled. File contents are fetched only when needed for SHA-256 computation and aren't stored — only the hashes, sizes, and paths. We do log each search and ingest (including IP address) for rate-limiting and abuse prevention.

For the full details, see the Privacy Policy and Terms of Service.

← back to home