Ragex.Git.CoChange (Ragex v0.18.4)

View Source

Co-change analysis: discover files (and functions) that frequently change together.

Walks the commit history and builds a co-occurrence matrix. If files A and B appear in the same commit N times, they have co-change weight N. The result is stored in an ETS table for fast querying.

Algorithm

  1. Fetch the last max_commits commits with --name-only.
  2. For each commit, record every pair of changed files.
  3. Store {file_a, file_b} => count in ETS.
  4. Optionally persist to ~/.ragex/cochange/<project_hash>.etf.

Examples

# Analyze co-change for the repo at /opt/project
{:ok, _} = CoChange.analyze("/opt/project")

# Query: what changes when lib/user.ex changes?
CoChange.for_file("lib/user.ex")
#=> [{"lib/user_test.exs", 42}, {"lib/accounts.ex", 18}, ...]

Summary

Functions

Analyze co-change patterns for the repository at path.

Clear all co-change data from memory.

Returns files that co-change with file_path, sorted by frequency.

Load persisted co-change data for a repository, if available.

Functions

analyze(path, opts \\ [])

@spec analyze(
  String.t(),
  keyword()
) :: {:ok, map()} | {:error, term()}

Analyze co-change patterns for the repository at path.

Options

  • :max_commits -- how many commits to analyze (default 500)
  • :persist -- write results to disk (default true)

Returns

{:ok, %{pairs: non_neg_integer(), commits_analyzed: non_neg_integer()}}

clear()

@spec clear() :: :ok

Clear all co-change data from memory.

for_file(file_path, opts \\ [])

@spec for_file(
  String.t(),
  keyword()
) :: [{String.t(), pos_integer()}]

Returns files that co-change with file_path, sorted by frequency.

Options

  • :min_count -- minimum co-change count to include (default 2)
  • :limit -- max results (default 20)

load(repo_root)

@spec load(String.t()) :: :ok | {:error, :not_found}

Load persisted co-change data for a repository, if available.