ref:93e9e00a58579c11e5c9b2dcacb60193a0b3baee

Fix 6 interop bugs found via git binary testing (18 failing tests)

1. Commit extra header ordering: preserve gpgsig position in extra_headers during parsing so encode_content emits headers in original order 2. Commit empty header value: don't add trailing space for valueless headers 3. Tag multiline extra headers: use continuation line encoding (space prefix) 4. Tag empty header value: same empty-value fix as commits 5. Filesystem ref listing: filter out .lock and .tmp files 6. Ref validation: add missing git-check-ref-format rules (control chars, space, ~, ^, :, ?, *, [, @{, dot-prefixed components, trailing dot) Closes #5 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SHA: 93e9e00a58579c11e5c9b2dcacb60193a0b3baee
Author: Cole Christensen <cole.christensen@macmillan.com>
Date: 2026-02-11 06:29
Parents: 543ccf6
5 files changed +500 -4
Type
lib/ex_git_objectstore/ref.ex +31 −0
@@ -173,9 +173,40 @@
String.starts_with?(ref_path, "/") ->
{:error, {:invalid_ref_name, ref_path, :leading_slash}}
has_control_chars?(ref_path) ->
{:error, {:invalid_ref_name, ref_path, :control_char}}
has_forbidden_chars?(ref_path) ->
{:error, {:invalid_ref_name, ref_path, :forbidden_char}}
String.contains?(ref_path, "@{") ->
{:error, {:invalid_ref_name, ref_path, :at_brace}}
has_dot_component?(ref_path) ->
{:error, {:invalid_ref_name, ref_path, :dot_component}}
String.ends_with?(ref_path, ".") ->
{:error, {:invalid_ref_name, ref_path, :trailing_dot}}
true ->
:ok
end
end
defp has_control_chars?(str) do
str
|> :binary.bin_to_list()
|> Enum.any?(fn byte -> byte < 0x20 or byte == 0x7F end)
end
defp has_forbidden_chars?(str) do
String.match?(str, ~r/[ ~^:?*\[]/)
end
defp has_dot_component?(ref_path) do
ref_path
|> String.split("/")
|> Enum.any?(&String.starts_with?(&1, "."))
end
@doc """