# `Exgit.Object.Tag`
[🔗](https://github.com/ivarvong/exgit/blob/v0.1.0/lib/exgit/object/tag.ex#L1)

Git annotated tag object.

Like `Exgit.Object.Commit`, a tag is represented as a message plus an
**ordered list of headers**. Unknown headers and continuation lines
(multi-line values such as embedded signatures) are preserved verbatim
and in order, so `decode |> encode` is byte-exact and re-encoding a
decoded tag never changes its SHA.

The `:object` field caches the validated `object` header as a raw
20-byte binary; `encode/1` reads only `:headers` and `:message`.
Convenience accessors (`type/1`, `tag/1`, `tagger/1`) extract
well-known headers.

`decode/1` validates the `object` header as a 40-char hex string.
Accessors on a decoded tag are infallible — a hostile remote cannot
DoS a walk/diff by shipping a tag with non-hex header bytes. See
`test/exgit/security/tag_malformed_hex_test.exs` for the
regression.

# `header`

```elixir
@type header() :: {name :: String.t(), value :: String.t()}
```

# `t`

```elixir
@type t() :: %Exgit.Object.Tag{
  headers: [header()],
  message: String.t(),
  object: binary()
}
```

# `decode`

```elixir
@spec decode(binary()) :: {:ok, t()} | {:error, term()}
```

# `encode`

```elixir
@spec encode(t()) :: iolist()
```

# `new`

```elixir
@spec new(keyword()) :: t()
```

# `sha`

```elixir
@spec sha(t()) :: Exgit.Object.sha()
```

# `sha_hex`

```elixir
@spec sha_hex(t()) :: String.t()
```

# `tag`

```elixir
@spec tag(t()) :: String.t()
```

# `tagger`

```elixir
@spec tagger(t()) :: String.t() | nil
```

# `type`

```elixir
@spec type(t()) :: String.t()
```

---

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