Skip to content
internal/scan
Edit
On this page

Package scan iterates all git objects (reachable and unreachable) and matches patterns against their textual content for history scrubbing.

#internal/scan

#internal/scan

Package scan iterates all git objects (reachable and unreachable) and matches patterns against their textual content for history scrubbing. Blobs, commit messages, and tag annotations are searched. Binary blobs (NUL in first 8KB) are skipped.

#Match

Go go
type Match struct

Match records a single pattern hit inside a git object.

#ScanResults

Go go
type ScanResults struct

ScanResults holds the aggregate output of a scan across all git objects.

#ScanOpts

Go go
type ScanOpts struct

ScanOpts configures which objects to scan and where to find them.

Exactly one of EntireHistory, FromSHA and Tips selects the object set; declaring none, or more than one, is an error rather than a precedence rule.

#AddAttribution

Go go
func AddAttribution(ctx context.Context, results *ScanResults, opts ScanOpts) error

AddAttribution enriches blob matches with commit and path information. For each match where ObjectType "blob" and Path "", it finds which commit(s) contain the blob and what file path it has. Uses git rev-list --all --objects to build a blob-to-path index. Unreachable blobs (not in rev-list output) keep empty Path/CommitSHA. When opts.GitDir is set, commands target that git directory.

#ScanNonObjects

Go go
func ScanNonObjects(ctx context.Context, pattern *regexp.Regexp, gitDir string) ([]Match, error)

ScanNonObjects scans non-git-object files for the given pattern.

The set it covers is everything a secret can sit in without being a git object:

- /config (tokens in remote URLs) and /COMMIT_EDITMSG; - every hook, at any depth, in BOTH the directory git runs hooks from (git resolves it, so core.hooksPath and linked worktrees are followed) and safegit's own hook stores, which is the location enumerator's answer -- one authority, so a store the enumerator learns about is swept without this file being told about it; - everything under safegit's own state directory except the rewrite journal, from the invoking worktree's git dir AND from the common one -- the same directory in an ordinary repository, but in a linked worktree the common one is where the repository-level state (config.json, the oplog) actually lives; - the tracked working-tree files git lists.

Binary files are skipped (NUL in first 8KB). Non-existent files are skipped.

#ScanObjectsMulti

Go go
func ScanObjectsMulti(ctx context.Context, patterns []*regexp.Regexp, opts ScanOpts) ([]*ScanResults, error)

ScanObjectsMulti iterates every object in the git object store once and searches for matches against multiple patterns simultaneously. Returns one ScanResults per pattern (same order as input). The reachable set and object iteration happen only once regardless of how many patterns are provided. Uses the same opts as ScanObjects; only EntireHistory mode is supported.

#ScanObjects

Go go
func ScanObjects(ctx context.Context, pattern *regexp.Regexp, opts ScanOpts) (*ScanResults, error)

ScanObjects iterates git objects and searches for pattern matches. The opts parameter controls which objects are scanned: - EntireHistory=true: uses cat-file --batch-all-objects (all objects including unreachable loose objects). Builds a reachable set to mark each match. - FromSHA set: uses rev-list --objects FromSHA..HEAD (reachable only). All matches are marked reachable by construction. - Tips set: uses rev-list --objects on those commits or tag objects, so an object set no ref points at yet can be scanned. All matches are marked reachable by construction (they are reachable from the given tips). - None set: returns an error.

When GitDir is set, commands target that git directory instead of CWD. SubmodulePath is set on every returned Match.

More tools from this site

  • claudestream Drive Claude Code from Python: run it as a subprocess and read its output as typed events, with async and sync sessions, sandbox policies, and tools you define in Python
  • claudewheel A TUI Claude Code Launcher that lets you have more than one profile, manage sessions lifecycle, pick the exact CC version, model to use (even older unlisted ones), pick which GitHub account to use, etc.
  • dirstat Fast, single-binary directory statistics CLI: every file under a tree grouped by format, with counts, sizes, and lines of code, as a colored terminal table or as JSON
  • fastware A batteries-included ASGI framework: msgspec JSON, a managed Granian server, dependency injection, SSE, WebSockets, auth, and a test client
  • go-toml-edit Zero-dep TOML editing library for Go with comment preservation
  • howmuchleft The fastest Claude Code statusline: context window, 5-hour, and weekly limit usage as three customizable gradient bars, rendering in about 6 ms
  • orxtra
  • pgdesign
  • predraw Declarative rendering pipeline: describe a scene in JSON and get SVG, PNG and WebP out, with light and dark style tokens, reusable components and text converted to path outlines
  • reposummary Turn a git repository's history into a Markdown journal: pick a time window or revision range and get a readable digest of what changed, optionally narrated by an LLM
  • rlsbl Release orchestration and project scaffolding CLI that bumps versions, validates a structured JSONL changelog, tags only the commit CI verified, and publishes to npm, PyPI, Go and more
  • saferm Command-line replacement for rm that archives every deletion with a mandatory reason and the context it ran in, so deleted files can be listed, inspected and restored
  • selfdoc Static Site Generator that builds a project's documentation site directly from its source code, so the docs can never drift from the code they describe, with SEO/AEO, first-class blog, search, and cross-project linking built in
  • strictcli
  • stricttest An always-on test-isolation floor: a pytest plugin and a Go env-hygiene module that make a test suite structurally unable to reach real credentials, the real HOME, the network, or the development repository.
  • wesktop A Python framework that turns an ASGI web app into a desktop application, serving it from a local Granian server and displaying it in a native OS window via pywebview
Search