# `Git.Branches`
[🔗](https://github.com/joshrotenberg/git_wrapper_ex/blob/main/lib/git/branches.ex#L1)

Higher-level branch workflow operations that compose multiple lower-level
`Git` commands.

All functions accept an optional keyword list. The `:config` key, when
present, must be a `Git.Config` struct and is forwarded to every underlying
git invocation.

# `cleanup_merged`

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

Finds branches merged into a target and deletes them.

## Options

  * `:target` - branch to check against (default: current branch)
  * `:force` - use force delete, `-D` (default: `false`)
  * `:exclude` - list of branch names to never delete
    (default: `["main", "master", "develop"]`)
  * `:dry_run` - just return the list without deleting (default: `false`)

The current branch and any branches in the `:exclude` list are always
skipped.

Returns `{:ok, [String.t()]}` with the list of deleted (or would-be-deleted)
branch names.

# `create_and_checkout`

```elixir
@spec create_and_checkout(
  String.t(),
  keyword()
) :: {:ok, Git.Checkout.t()} | {:error, term()}
```

Creates a new branch and checks it out in one call.

Equivalent to `git checkout -b <branch_name>`.

Returns `{:ok, Git.Checkout.t()}` on success.

# `current`

```elixir
@spec current(keyword()) :: {:ok, String.t()} | {:error, term()}
```

Returns the name of the current branch.

Uses `git rev-parse --abbrev-ref HEAD`.

Returns `{:ok, String.t()}` on success.

# `divergence`

```elixir
@spec divergence(String.t(), String.t(), keyword()) ::
  {:ok, %{ahead: non_neg_integer(), behind: non_neg_integer()}}
  | {:error, term()}
```

Returns ahead/behind counts between two branches.

Uses `git rev-list --count --left-right branch1...branch2`.

Returns `{:ok, %{ahead: non_neg_integer(), behind: non_neg_integer()}}`.

# `exists?`

```elixir
@spec exists?(
  String.t(),
  keyword()
) :: {:ok, boolean()} | {:error, term()}
```

Checks whether a branch exists locally.

Uses `git rev-parse --verify refs/heads/<branch_name>`.

Returns `{:ok, true}` when the branch exists, `{:ok, false}` otherwise.

# `merged`

```elixir
@spec merged(keyword()) :: {:ok, [Git.Branch.t()]} | {:error, term()}
```

Lists branches that have been merged into the current branch or a specified
target.

## Options

  * `:target` - branch to check against (default: current branch)

Returns `{:ok, [Git.Branch.t()]}`.

# `no_merged`

```elixir
@spec no_merged(keyword()) :: {:ok, [Git.Branch.t()]} | {:error, term()}
```

Lists branches that have NOT been merged into the current branch or a
specified target.

## Options

  * `:target` - branch to check against (default: current branch)

Returns `{:ok, [Git.Branch.t()]}`.

# `recent`

```elixir
@spec recent(keyword()) ::
  {:ok,
   [
     %{
       name: String.t(),
       date: String.t(),
       author: String.t(),
       subject: String.t()
     }
   ]}
  | {:error, term()}
```

Lists branches sorted by most recent commit.

## Options

  * `:count` - maximum number of branches to return (default: `10`)

Uses `git for-each-ref` with `--sort=-committerdate`.

Returns `{:ok, [%{name: String.t(), date: String.t(), author: String.t(), subject: String.t()}]}`.

# `rename`

```elixir
@spec rename(String.t(), String.t(), keyword()) :: {:ok, :done} | {:error, term()}
```

Renames a branch.

Uses `git branch -m <old_name> <new_name>`.

Returns `{:ok, :done}` on success.

---

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