Specification · v0.1.0

gref

git-backed references.

A compact, human-writable string that identifies a path in a remote git-hosted repository — without requiring a full URL.

owner/repo@ref:path

Objectives

gref aims to be:

  • Obvious — readable at a glance; looks like the shorthand people already type (owner/repo, owner/repo@v1, owner/repo:path).
  • Minimal — only the pieces needed to locate content: host, owner, repository, ref, and path.
  • Portable — the same string can be parsed by CLIs, package managers, agent tools, and config files.
  • Host-friendly — defaults to a two-segment owner/repo form, with an optional host prefix for Gist, GitLab, and other forges.

gref specifies string syntax and structure. How a consumer downloads content, which ref or path to use when omitted, authentication, and caching are application-defined.

Terminology

Term Meaning
host DNS name of the forge (e.g. github.com, gitlab.com)
owner Account, user, or organization
repo Repository name (or gist id on gist.github.com)
ref Branch, tag, or commit-ish after @
path Repository-relative file or directory path after :; trailing / means folder

Format

The general form is:

[host/]owner/repo[@ref][:path]

Whitespace is not allowed anywhere in a gref. Matching is case-sensitive for all components except where a host itself treats names case-insensitively (application-defined when resolving).

Minimal form

owner/repo

Implies no explicit host, ref, or path. Consumers apply their own defaults (see Application defaults).

With ref

owner/repo@main
owner/[email protected]
owner/repo@abc1234
owner/repo@feature/foo

ref is everything after the first @ following owner/repo, up to (but not including) a following :path, if any. It must not contain whitespace or :. It may contain / (common in branch names).

With path

owner/repo:src/app.cs
owner/repo@v1:docs/readme.md
owner/repo@main:src/

path is everything after the first : that follows the repository segment (and optional @ref). Paths use / as the separator. A leading / is not required; consumers should treat foo/bar and /foo/bar as the same repository-relative path.

A path that ends with / denotes a folder (tree) reference rather than a file (blob) reference. Consumers that resolve content should treat src/app.cs as a file and src/ as a directory.

With host

github.com/owner/repo@main:path
gist.github.com/owner/gistid
gitlab.com/owner/repo@main:path

When host is present it is a domain-like token: labels of alphanumerics and hyphens, separated by dots, ending with an alphabetic TLD of length ≥ 2.

Components

Host

Optional. When omitted, the consumer supplies a default (commonly github.com).

Host Notes
github.com Typical default for two-segment owner/repo
gist.github.com repo is the gist id
gitlab.com Same shape as GitHub

Other hosts are valid in the grammar; resolution is application-defined.

Owner

Non-empty. Must not contain /, @, :, or whitespace.

Repo

Non-empty. Must not contain @, :, or whitespace. Must not contain / (a / after owner/ starts a path only when using other URI forms — in gref, the repository name is a single segment).

On gist.github.com, repo is the gist identifier.

Ref

Optional. Branch name, tag name, or other commit-ish accepted by the host. Must not contain : or whitespace. May contain /.

When omitted, resolution of ref is application-defined. Implementations MAY:

  • default to the repository’s default branch (commonly main or master);
  • default to the latest published version (for example the newest release tag or package version the tool understands); or
  • require an explicit @ref and reject or error when it is missing.

For reproducible shares (lockfiles, citations), prefer tags or commit SHAs over floating branch names.

Path

Optional. Repository-relative path to a file or directory.

  • If path does not end with /, it denotes a file (blob) reference.
  • If path ends with /, it denotes a folder (tree) reference.

When omitted, the default path is application-defined (for example a well-known entry file, or the repository root as a whole).

Grammar

Normative structure (character classes for owner / repo / host are structural; see also Common subset):

gref        = [ host "/" ] owner "/" repo [ "@" ref ] [ ":" path ]

host        = label *( "." label ) "." tld
label       = alnum *63( alnum / "-" )
tld         = 2*alpha

owner       = 1*( unreserved )
repo        = 1*( unreserved )
ref         = 1*( %x21-39 / %x3B-7E )   ; non-empty; no ":" or space
path        = 1*( %x21-7E )             ; non-empty; no space

unreserved  = %x21-2E / %x30-39 / %x3B-3F / %x41-7E
              ; printable ASCII except space, "/" (0x2F), ":" (0x3A), "@" (0x40)
              ; — i.e. no gref delimiters
alnum       = ALPHA / DIGIT
alpha       = %x41-5A / %x61-7A

Parsing order:

  1. If the string is an absolute URL of a known forge shape, first normalize it into gref form, then parse.
  2. Else match the gref grammar.

A parse failure means the string is not a gref (it may still be a local path or another identifier — applications decide the fallback order).

Common subset (informative)

Many GitHub-oriented tools additionally restrict:

Component Common restriction
owner Starts with alphanumeric; hyphens allowed; max length 39
repo Alphanumerics, ., _, -; max length 100

These limits are not required by gref. Consumers talking to a specific API may tighten validation for that host.

Examples

# Defaults for host / ref / path left to the application
kzu/sandbox

# Explicit ref and path (file)
kzu/[email protected]:src/hello.cs
kzu/sandbox@main:program.cs
kzu/sandbox@feature/foo:src/app.cs

# Folder path (trailing slash)
kzu/sandbox@main:src/
kzu/sandbox@v1:docs/guides/

# Explicit host
github.com/kzu/sandbox@main:hello.cs
github.com/kzu/sandbox@main:src/

# GitHub Gist (repo = gist id)
gist.github.com/kzu/0ac826dc7de666546aaedd38e5965381
gist.github.com/kzu/0ac826dc7de666546aaedd38e5965381:run.cs

# GitLab
gitlab.com/kzu/runcs@main:program.cs

Round-trip display

A structured gref should format back to:

[host/]owner/repo[@ref][:path]

Omit optional parts that are unset. Do not invent defaults when serializing unless the application documents that behavior.

URL convenience forms

Consumers MAY accept absolute HTTPS URLs pasted from a browser and normalize them to gref form before parsing.

GitHub blob URL (file)

https://github.com/{owner}/{repo}/blob/{ref}/{path}
→ github.com/{owner}/{repo}@{ref}:{path}

GitHub tree URL (folder)

https://github.com/{owner}/{repo}/tree/{ref}/{path}
→ github.com/{owner}/{repo}@{ref}:{path}/

The trailing / on the gref path marks a folder reference. If the tree URL points at the repository root (…/tree/{ref} with no further path), applications MAY omit :path or use a host-specific root convention.

GitHub Gist URL

https://gist.github.com/{owner}/{gistid}
→ gist.github.com/{owner}/{gistid}

GitLab blob URL (file)

https://gitlab.com/{owner}/{repo}/-/blob/{ref}/{path}
→ gitlab.com/{owner}/{repo}@{ref}:{path}

GitLab tree URL (folder)

https://gitlab.com/{owner}/{repo}/-/tree/{ref}/{path}
→ gitlab.com/{owner}/{repo}@{ref}:{path}/

Other URL shapes are application-defined. Unknown hosts or shapes should not be forced into a gref.

Form Example Relationship
Go / module path github.com/owner/repo Host + owner + repo; no @ref:path in the same way
Git SSH [email protected]:owner/repo.git Transport URL, not a gref
Raw content URL https://raw.githubusercontent.com/... Resolved artifact URL; gref is the input shorthand

gref is intentionally close to how developers already cite repository paths in chat and CLIs.

Application defaults (non-normative)

These defaults are not required by gref; they are policies of tools that resolve grefs to downloadable content.

Omitted Common choices (implementations MAY pick any)
host github.com
ref Repository default branch (main / master); or latest published version (e.g. newest release tag); or require @ref
path A conventional entry file, else repository root

No single default for ref is mandated: a CLI that tracks floating source may use the default branch; a package-style runner may pin “latest release”; a strict resolver may demand @ref every time.

Local path disambiguation is also application-defined. A common pattern:

  1. If the input exists as a local file, treat it as a path.
  2. Else if gref parse succeeds, treat it as remote.
  3. Else error.

Security considerations

  • grefs can point at arbitrary public (or private) repositories. Tools that execute fetched content must treat it as untrusted code.
  • Prefer fixed refs (tags or commit SHAs) for reproducible installs; floating branches (@main) change over time.
  • Validate that resolved download URLs stay on the expected host before fetching.
  • Do not expand environment variables or shell metacharacters inside gref components.

Versioning of this document

This specification is versioned with semantic-style tags (vMAJOR.MINOR.PATCH):

  • MAJOR — incompatible grammar or meaning changes
  • MINOR — backward-compatible additions (new optional forms, hosts)
  • PATCH — clarifications, examples, non-normative text

The latest published version is always available at gref.sh.

License

This specification is available under the MIT License. See license.txt.