# `Git.Commands.Diff`
[🔗](https://github.com/joshrotenberg/git_wrapper_ex/blob/main/lib/git/commands/diff.ex#L1)

Implements the `Git.Command` behaviour for `git diff`.

Supports working-tree diffs, staged (cached) diffs, stat-only output,
comparing against a specific ref, and limiting to a path.

# `t`

```elixir
@type t() :: %Git.Commands.Diff{
  diff_filter: String.t() | nil,
  find_copies: boolean(),
  find_renames: boolean(),
  ignore_all_space: boolean(),
  ignore_space_at_eol: boolean(),
  ignore_space_change: boolean(),
  name_only: boolean(),
  name_status: boolean(),
  numstat: boolean(),
  path: String.t() | nil,
  ref: String.t() | nil,
  ref_end: String.t() | nil,
  reverse: boolean(),
  staged: boolean(),
  stat: boolean(),
  unified: non_neg_integer() | nil
}
```

# `args`

```elixir
@spec args(t()) :: [String.t()]
```

Returns the argument list for `git diff`.

Options:
- `:staged` — adds `--cached` to show staged changes
- `:stat` — adds `--stat` for file-level summary instead of full patch
- `:numstat` — adds `--numstat` for machine-readable per-file insertion and
  deletion counts (parsed into `files` with exact counts)
- `:name_only` — adds `--name-only` for listing just file paths
- `:name_status` — adds `--name-status` for file paths with status letters
- `:ignore_all_space` — adds `-w`
- `:ignore_space_change` — adds `-b`
- `:ignore_space_at_eol` — adds `--ignore-space-at-eol`
- `:find_renames` — adds `-M`
- `:find_copies` — adds `-C`
- `:reverse` — adds `-R` to swap the two sides
- `:unified` — adds `-U<n>` to set the number of context lines
- `:diff_filter` — adds `--diff-filter=<value>` (e.g. `"ACMR"`)
- `:ref` — adds a ref to compare against (e.g., `"HEAD~1"`)
- `:ref_end` — when set with `:ref`, compares `ref ref_end` (two-ref diff)
- `:path` — adds `-- <path>` to limit the diff

## Examples

    iex> Git.Commands.Diff.args(%Git.Commands.Diff{})
    ["diff"]

    iex> Git.Commands.Diff.args(%Git.Commands.Diff{staged: true, stat: true})
    ["diff", "--cached", "--stat"]

    iex> Git.Commands.Diff.args(%Git.Commands.Diff{numstat: true, ignore_all_space: true})
    ["diff", "--numstat", "-w"]

    iex> Git.Commands.Diff.args(%Git.Commands.Diff{find_renames: true, unified: 0})
    ["diff", "-M", "-U0"]

    iex> Git.Commands.Diff.args(%Git.Commands.Diff{ref: "HEAD~1", path: "lib/"})
    ["diff", "HEAD~1", "--", "lib/"]

# `parse_output`

```elixir
@spec parse_output(String.t(), non_neg_integer()) ::
  {:ok, Git.Diff.t()} | {:error, {String.t(), non_neg_integer()}}
```

Parses the output of `git diff`.

On success (exit code 0), returns `{:ok, %Git.Diff{}}`.
On failure, returns `{:error, {stdout, exit_code}}`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
