Git.Changes (git v0.4.0)

Copy Markdown View Source

Higher-level change analysis helpers that compose lower-level Git functions.

Provides structured views of file changes between refs, uncommitted work, merge conflicts, and change summaries.

All functions accept an optional keyword list. Use :config to specify the repository via a Git.Config struct; when omitted a default config is built from the environment.

Summary

Functions

Returns structured file changes between two refs.

Detects files with merge conflicts.

Returns only staged changes as a diff.

Returns summary statistics of unstaged working tree changes.

Returns a one-call summary of changes between two refs.

Returns structured info about all uncommitted changes.

Returns only unstaged changes as a diff.

Functions

between(ref1, ref2, opts \\ [])

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

Returns structured file changes between two refs.

Uses git diff --name-status ref1 ref2 to get per-file status. Each entry is a map with :status, :path, and :old_path (non-nil for renames and copies).

Options

  • :config - a Git.Config struct
  • :stat - when true, also includes line-level stats per file

Examples

{:ok, changes} = Git.Changes.between("v1.0.0", "v2.0.0")
hd(changes).status  #=> :added
hd(changes).path    #=> "lib/new_file.ex"

conflicts(opts \\ [])

@spec conflicts(keyword()) :: {:ok, [String.t()]} | {:error, term()}

Detects files with merge conflicts.

Uses git ls-files --unmerged to reliably detect conflicted files, then deduplicates paths since each conflicted file appears multiple times in the unmerged listing.

Options

Examples

{:ok, conflicts} = Git.Changes.conflicts()
conflicts  #=> ["lib/conflicted.ex"]

staged(opts \\ [])

@spec staged(keyword()) :: {:ok, Git.Diff.t()} | {:error, term()}

Returns only staged changes as a diff.

Uses Git.diff(staged: true, stat: true) to show what is in the index but not yet committed.

Returns {:ok, Git.Diff.t()}.

stats(opts \\ [])

@spec stats(keyword()) ::
  {:ok,
   %{
     files_changed: non_neg_integer(),
     insertions: non_neg_integer(),
     deletions: non_neg_integer()
   }}
  | {:error, term()}

Returns summary statistics of unstaged working tree changes.

Uses Git.diff(stat: true) and extracts file count, insertions, and deletions into a simple map.

Returns {:ok, %{files_changed: n, insertions: n, deletions: n}}.

summary(ref1, ref2, opts \\ [])

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

Returns a one-call summary of changes between two refs.

Includes the number of files changed, total insertions and deletions, and per-file details.

Options

Examples

{:ok, summary} = Git.Changes.summary("v1.0.0", "v2.0.0")
summary.files_changed  #=> 3
summary.insertions     #=> 42
summary.deletions      #=> 10

uncommitted(opts \\ [])

@spec uncommitted(keyword()) :: {:ok, map()} | {:error, term()}

Returns structured info about all uncommitted changes.

Groups status entries into :staged (files in the index), :modified (tracked files with working tree changes), and :untracked files.

Options

Examples

{:ok, uncommitted} = Git.Changes.uncommitted()
uncommitted.staged    #=> [%{path: "lib/foo.ex", status: :modified}]
uncommitted.untracked #=> ["new_file.ex"]

unstaged(opts \\ [])

@spec unstaged(keyword()) :: {:ok, Git.Diff.t()} | {:error, term()}

Returns only unstaged changes as a diff.

Uses Git.diff(stat: true) to show working tree changes that have not been staged.

Returns {:ok, Git.Diff.t()}.