# `Minga.Git.Backend`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga/git/backend.ex#L1)

Behaviour for git operations.

The default implementation (`Minga.Git.System`) shells out to the `git`
CLI. In tests, `Minga.Git.Stub` returns inert responses without
spawning OS processes.

Configure via:

    config :minga, git_module: Minga.Git.System   # default
    config :minga, git_module: Minga.Git.Stub      # tests

# `ahead_behind`

```elixir
@callback ahead_behind(git_root :: String.t()) ::
  {:ok, non_neg_integer(), non_neg_integer()} | :error
```

# `blame_line`

```elixir
@callback blame_line(
  git_root :: String.t(),
  relative_path :: String.t(),
  line :: non_neg_integer()
) :: {:ok, String.t()} | :error
```

# `branch_create`

```elixir
@callback branch_create(git_root :: String.t(), name :: String.t()) ::
  :ok | {:error, String.t()}
```

# `branch_delete`

```elixir
@callback branch_delete(git_root :: String.t(), name :: String.t(), force :: boolean()) ::
  :ok | {:error, String.t()}
```

# `branch_list`

```elixir
@callback branch_list(git_root :: String.t()) ::
  {:ok, [Minga.Git.BranchInfo.t()]} | {:error, String.t()}
```

# `branch_switch`

```elixir
@callback branch_switch(git_root :: String.t(), name :: String.t()) ::
  :ok | {:error, String.t()}
```

# `commit`

```elixir
@callback commit(git_root :: String.t(), message :: String.t(), opts :: keyword()) ::
  {:ok, String.t()} | {:error, String.t()}
```

# `current_branch`

```elixir
@callback current_branch(git_root :: String.t()) :: {:ok, String.t()} | :error
```

# `diff`

```elixir
@callback diff(git_root :: String.t(), opts :: Minga.Git.diff_opts()) ::
  {:ok, String.t()} | {:error, String.t()}
```

# `discard`

```elixir
@callback discard(git_root :: String.t(), path :: String.t()) ::
  :ok | {:error, String.t()}
```

# `fetch_remotes`

```elixir
@callback fetch_remotes(git_root :: String.t(), opts :: keyword()) ::
  :ok | {:error, String.t()}
```

# `last_commit_message`

```elixir
@callback last_commit_message(git_root :: String.t()) :: {:ok, String.t()} | :error
```

# `log`

```elixir
@callback log(git_root :: String.t(), opts :: keyword()) ::
  {:ok, [Minga.Git.log_entry()]} | {:error, String.t()}
```

# `pull`

```elixir
@callback pull(git_root :: String.t(), opts :: keyword()) :: :ok | {:error, String.t()}
```

# `push`

```elixir
@callback push(git_root :: String.t(), opts :: keyword()) :: :ok | {:error, String.t()}
```

# `root_for`

```elixir
@callback root_for(path :: String.t()) :: {:ok, String.t()} | :not_git
```

# `show_head`

```elixir
@callback show_head(git_root :: String.t(), relative_path :: String.t()) ::
  {:ok, String.t()} | :error
```

# `show_staged`

```elixir
@callback show_staged(git_root :: String.t(), relative_path :: String.t()) ::
  {:ok, String.t()} | :error
```

# `stage`

```elixir
@callback stage(git_root :: String.t(), paths :: String.t() | [String.t()]) ::
  :ok | {:error, String.t()}
```

# `stage_patch`

```elixir
@callback stage_patch(git_root :: String.t(), patch :: String.t()) ::
  :ok | {:error, String.t()}
```

# `stash`

```elixir
@callback stash(git_root :: String.t(), opts :: keyword()) :: :ok | {:error, String.t()}
```

# `stash_drop`

```elixir
@callback stash_drop(git_root :: String.t(), index :: non_neg_integer()) ::
  :ok | {:error, String.t()}
```

# `stash_list`

```elixir
@callback stash_list(git_root :: String.t()) ::
  {:ok, [Minga.Git.stash_entry()]} | {:error, String.t()}
```

# `stash_pop`

```elixir
@callback stash_pop(git_root :: String.t()) :: :ok | {:error, String.t()}
```

# `status`

```elixir
@callback status(git_root :: String.t(), opts :: keyword()) ::
  {:ok, [Minga.Git.status_entry()]} | {:error, String.t()}
```

# `unstage`

```elixir
@callback unstage(git_root :: String.t(), paths :: String.t() | [String.t()]) ::
  :ok | {:error, String.t()}
```

# `unstage_all`

```elixir
@callback unstage_all(git_root :: String.t()) :: :ok | {:error, String.t()}
```

---

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