Git: is_safe_refname rejects legal git ref names containing '+'
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
# Git: `is_safe_refname` rejects legal git ref names containing `+` (and other git-valid characters)
## Summary
`crates/buzz-relay/src/api/git/manifest.rs` — `is_safe_refname()` allows only `[a-zA-Z0-9_./-]` (plus the structural `refs/` checks). Git's own rules (`git check-ref-format`) additionally permit characters like `+`, `@`, `=`, `,`, `!`, and `]` in ref components. Refs that git happily creates therefore cannot be pushed to Buzz at all.
This is not hypothetical: `OriginTrail/dkg` (a real upstream repo) contains the branch
```
refs/heads/test/842+841-devnet
```
and pushing it fails with `HTTP 400` — it is the single ref out of 1,339 that cannot be mirrored into Buzz git.
## Reproduction
```bash
git init t && cd t && git commit --allow-empty -m x
git branch "test/842+841-devnet" # git accepts this name fine
git push refs/heads/test/842+841-devnet:refs/heads/test/842+841-devnet
# → error: RPC failed; HTTP 400
```
`git check-ref-format --branch "test/842+841-devnet"` exits 0 — the name is legal git.
## Suggested fix
Widen the allowed alphabet in `is_safe_refname` to the git-legal set while keeping the structural protections that actually matter for the object-store keys (no `..`, no `//`, no control chars, no leading/trailing slash, `refs/` prefix). Since refnames are used as object-store key components, characters outside the current set could be percent-encoded at the storage boundary instead of rejected at the protocol boundary — the doc comment already notes the predicate is shared symmetrically by write validation and hydration, so a single encode/decode pair at that seam keeps the "valid CAS, un-clone-able output" invariant intact.
A conservative first step that covers the observed real-world case: add `+` (and ideally `@`) to the alphabet — neither has meaning to the object-store key scheme nor to path traversal.
## Environment
Relay at `63496cc1d`; observed 2026-08-01 while mirroring `OriginTrail/dkg`.
Contributor guide
Research direction
Start in crates/buzz-relay/src/api/git/manifest.rs at is_safe_refname(), then compare its allowed characters and structural checks with git check-ref-format --branch using the reproduced test/842+841-devnet name. Done means legal Git refs such as the reported + case can be pushed and mirrored while the existing protections against .., //, control characters, and invalid slash placement remain intact.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, rust
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100