libra ls-remote
Command reference for `libra ls-remote`
List references advertised by a remote repository without downloading objects or updating local refs.
libra ls-remote [OPTIONS] <repository> [patterns...]
<repository> can be a configured remote name when run inside a Libra repository, a URL, or a local Git/Libra repository path.
Options
| Flag | Description | Example |
|---|---|---|
--heads |
Show only refs/heads/* branch refs |
libra ls-remote --heads origin |
-t, --tags |
Show only refs/tags/* tag refs |
libra ls-remote --tags origin |
--refs |
Omit HEAD and peeled tag refs ending in ^{} |
libra ls-remote --refs origin |
--get-url |
Resolve and print the configured URL without contacting the remote | libra ls-remote --get-url origin |
--exit-code |
Exit with status 2 when discovery succeeds but no refs match | libra ls-remote --exit-code origin main |
--sort <KEY> |
Sort refs by refname, -refname, version:refname, or -version:refname |
libra ls-remote --sort=version:refname --tags origin |
--symref |
Print symbolic-ref targets advertised by the remote (e.g. ref: refs/heads/main\tHEAD) above the matching ref |
libra ls-remote --symref origin |
patterns... |
Match full ref names or trailing path components; * and ? follow Git-style glob behavior and can match / |
libra ls-remote origin main 'refs/heads/*' |
Human Output
Each matching ref is printed as:
<object-id> <refname>
Example:
4f3c2d1a... HEAD
4f3c2d1a... refs/heads/main
JSON Output
With --json, output uses the standard command envelope:
{
"ok": true,
"command": "ls-remote",
"data": {
"remote": "origin",
"url": "https://example.com/repo.git",
"heads_only": false,
"tags_only": false,
"refs_only": false,
"get_url": false,
"exit_code": false,
"sort": null,
"patterns": [],
"entries": [
{
"hash": "4f3c2d1a...",
"refname": "refs/heads/main"
}
]
}
}
Examples
# List all refs from a named remote
libra ls-remote origin
# List all refs from a URL directly (no remote registration required)
libra ls-remote https://example.com/repo.git
# Restrict to branches matching a pattern
libra ls-remote --heads origin main
# Resolve a configured remote URL without discovery
libra ls-remote --get-url origin
# Sort tags with version-aware refname ordering
libra ls-remote --sort=version:refname --tags origin
# Show symbolic-ref targets (HEAD) advertised by the remote
libra ls-remote --symref origin
# Structured JSON envelope for agents, tags only
libra --json ls-remote --tags origin
The same banner is rendered by libra ls-remote --help so the doc and
the CLI surface stay in sync (cross-cutting --help EXAMPLES rollout,
see docs/development/commands/_general.md item B).
Error Handling
| Scenario | Error Code | Exit | Hint |
|---|---|---|---|
| Repository/config read failure | LBR-IO-001 |
128 | -- |
| Named remote not found, invalid or unsupported URL, or invalid ref pattern | LBR-CLI-003 |
129 | Use libra remote -v to inspect configured remotes |
| Unsupported sort key | LBR-CLI-002 |
129 | Use --sort=refname or --sort=version:refname |
| Other remote authentication or authorization rejection | LBR-AUTH-002 |
128 | Check SSH key / HTTP credentials and repository access rights |
| SSH public-key rejection during discovery | LBR-AUTH-002 |
128 | Check the selected key, SSH agent and repository access; see the SSH setup guide |
| Network or transport failure | LBR-NET-001 |
128 | Check the remote URL and network connectivity |
| pkt-line discovery framing or protocol failure | LBR-NET-002 |
128 | Check that the remote serves Git data and a proxy has not altered the response |
| Other discovery failure | LBR-NET-002 |
128 | -- |
| Human output write failure, including broken pipe | LBR-IO-001 |
128 | -- |
| JSON/machine output write failure (except broken pipe) | LBR-IO-002 |
128 | -- |
| Broken pipe while writing JSON/machine output | no error envelope | 0 | Downstream consumer stopped reading |
--exit-code with no matching refs |
no error envelope | 2 | Treat status 2 as the documented no-match signal |
Notes
ls-remoteperforms only protocol discovery (the in-process equivalent ofgit-upload-pack --advertise-refsfor local Git repositories — Libra reads their refs directly).- It does not write objects, remote-tracking refs, config, or working-tree files.
--headsand--tagscan be combined to show both branch and tag refs while excludingHEAD.--get-urlexits before protocol discovery and prints the same redacted URL form used by remote diagnostics.--exit-codeis a silent script signal: no matches returns status 2 without rendering an error.--symrefprints aref: <target>\t<name>line above a symbolic ref's own OID line, sourced from the remote's advertisedsymref=capabilities (typicallyHEAD). It is reported only for symrefs whose name survives the active filters. Git remotes and local Git repositories (served viagit-upload-pack) advertisesymref=HEAD:…, so HEAD's target is printed. Local Libra repositories advertise nosymref=capability, so noref:line is printed for them — Libra never synthesizes a symref from a localHEAD(an intentional difference from Git); the JSON envelope then omits thesymrefsarray.
Malformed HTTP(S) discovery responses
During HTTP(S) reference discovery, Libra rejects a zero-byte advertisement and
malformed pkt-line frames, including short or non-hexadecimal headers, frame
lengths below four, and truncated payloads. A valid 0000 flush remains distinct
from an absent response; a valid empty-repository advertisement is supported.
An unsupported object-format capability reports the fixed message
Unsupported object format capability without echoing its remote value.
Check that the URL points to a Git smart HTTP service and that a proxy has not
truncated or replaced the response; then retry.
pkt-line error classification
Detected pkt-line framing errors return LBR-NET-002 (exit 128), including an
empty HTTP(S) discovery advertisement. Ordinary connection failures, resets and
timeouts return LBR-NET-001 (exit 128). Verify the Git service and any proxy
response when a protocol error occurs. Discovery framing errors use the hint
check that the remote serves Git data and that a proxy has not altered the response.
This classification applies to reference discovery. SSH authentication and host-trust errors are described below; local configuration read errors keep their existing error codes.
SSH advertisement error handling
SSH advertisement lengths 0001 through 0003, incomplete headers (including
zero-byte EOF), and truncated payloads return LBR-NET-002. The fixed protocol
reason and marker are retained without captured SSH stdout/stderr.
An incomplete required discovery header has two prioritized exceptions. A recognized host-key
diagnostic with local SSH exit status 255 returns fixed verification guidance and
LBR-NET-001; this does not verify the remote fingerprint. A complete
Permission denied (<method-list>) diagnostic containing the exact publickey
method, direct exit status 255 and no stdout bytes returns the fixed public-key
message with LBR-AUTH-002. Because stderr can be forged, this code does not prove
why access was denied. All other missing advertisements remain LBR-NET-002, and
original SSH diagnostic text is hidden.
After an incomplete required header, Libra allows up to 100 milliseconds to observe the SSH exit status, then requests termination if needed. Other read errors request termination immediately. The status window, direct-child reap and output collection share a two-second cleanup deadline. Protocol, typed host-trust, and public-key authentication errors take precedence over secondary cleanup warnings. Ordinary IO and timeout errors keep their transport classification and may include a fixed local cleanup warning. Termination can change the observed exit status. This does not promise cleanup of arbitrary descendant processes.
Clone places targeted host-verification guidance in its structured hints. The
other command boundaries retain fixed host guidance in the message and their
existing LBR-NET-001 network hint. Human, JSON and machine diagnostics omit raw
captured remote stderr in either case.
The git:// discovery and object-fetch paths preserve the listed frame errors as
LBR-NET-002. All asynchronous readers reject non-ASCII/non-hexadecimal headers
with fixed protocol reasons. HTTP(S) discovery/advertisement framing is unchanged.
SSH authentication and captured diagnostics
Libra invokes SSH with BatchMode=yes for non-interactive, non-TTY, JSON and
machine callers. In a human terminal with an effective ask policy
(ssh.strictHostKeyChecking unset or ask), a first connection to an unknown
SSH host shows a Git-compatible fingerprint confirmation prompt; accepting it
writes the host key to your OpenSSH known-hosts destination and the original
command continues, while rejecting, EOF or a changed host key fails closed.
Libra never prompts for a private-key passphrase - load or unlock an encrypted
key in ssh-agent before retrying. For host trust, verify the fingerprint
through a trusted provider console or another trusted channel before manually
updating ~/.ssh/known_hosts, or make a separate interactive SSH connection and
compare the displayed fingerprint. For example, ssh -T git@github.com uses
GitHub; use the actual repository SSH user, host and port. Do not accept a
fingerprint that has not been verified.
For the strict discovery-only public-key rejection above, the fixed hint asks you
to check libra config list --ssh-keys, your SSH agent and repository access, and
links the SSH setup guide.
The config command requires an existing Libra repository; when using a URL from
outside one, inspect your SSH configuration and agent directly.
For at least 30 days after v0.24.1 is released and through at least the next
patch release, whichever is later, automation should accept both LBR-AUTH-002
and the legacy LBR-NET-002 for this SSH discovery failure.
ssh.strictHostKeyChecking retains its existing ask, yes, accept-new and
no values. ask leaves that SSH option to the user's SSH configuration;
BatchMode=yes still prevents interactive decisions. Explicit values are
forwarded to SSH. Choose a host-trust policy appropriate to your repository.
SSH stderr is always captured, including in terminal sessions. It is drained from process startup, retaining at most 64 KiB while counting and hashing the remaining bytes. User-facing errors contain fixed text and a local exit status when available. Raw remote stderr is neither printed nor logged. Debug diagnostics contain only the status, total and retained byte counts, and a SHA-256 digest of the collected stream. Failed or cancelled collection may prevent these metadata from being reported; no completed digest is claimed in that case. Hashing work is proportional to the number of bytes drained.
SSH reference advertisements and receive-pack responses each have a 16 MiB
aggregate limit. An oversized advertisement fails with LBR-NET-001 and guidance
to use the repository’s HTTPS URL if available, or ask its maintainer to reduce refs. An oversized push response fails with LBR-NET-001
and guidance to push fewer refs; it is not accepted as a truncated success.
These limits can affect repositories with very large ref sets or updates. The
streamed fetch pack is not subject to this cap. A failed push response does not
prove that the server rolled back its refs: inspect the remote state before
retrying. Existing IO timeouts still apply.
After a complete discovery advertisement, Libra allows up to 100 milliseconds for SSH to exit before requesting termination, within a two-second total cleanup deadline. Captured-output tasks are cancelled when their owner exits or their deadline expires, including when a descendant keeps a pipe open.
SSH host identity and diagnostic collection
SSH host identity changes retain a distinct fixed warning: the change may indicate interception or legitimate key rotation. Verify the new fingerprint through a trusted channel before replacing an existing known_hosts entry; do not bypass host-key checking. Unknown and changed host keys both use LBR-NET-001, but their fixed messages and guidance differ.
A stderr collection timeout does not by itself discard complete protocol output and an observed local exit status. Non-zero exit status and primary read errors still fail the operation. Unavailable diagnostics produce only a fixed debug notice, without fabricated empty-stream counts or digests. Stdout collection or process-wait failures retain their normal error handling.
SSH limits and host-classification boundaries
These fixed 16 MiB advertisement and receive-pack response limits apply only to Libra's SSH transport. The HTTPS and Git transports do not impose this particular cap. If the server provides an HTTPS endpoint, use its HTTPS remote URL when an SSH advertisement exceeds the cap; this does not require a read-only user to change the server's refs. Otherwise, ask the repository maintainer to reduce the advertised ref set. The streamed fetch pack remains outside this aggregate cap.
Host-trust classification requires an incomplete first header with no stdout bytes observed, local exit 255 and a recognized retained stderr pattern. Once any stdout byte arrives, including a partial header, host-like stderr cannot select host-specific guidance. Failures after a complete advertisement retain fixed generic diagnostics. The pre-advertisement pattern remains a diagnostic heuristic, not fingerprint verification.
A successful discovery whose child waits for a request normally incurs the full 100 ms native-exit observation window, once per discovery operation. This is separate from the two-second direct-child cleanup budget; no benchmark or arbitrary-descendant cleanup guarantee is implied.
Strict pkt-line headers
A pkt-line header must contain exactly four ASCII hexadecimal digits (0–9,
a–f or A–F). Fetch streaming, git:// advertisements and SSH advertisements
reject leading signs such as +004, whitespace, non-hexadecimal text and invalid
UTF-8. These failures return LBR-NET-002 (exit 128), with fixed reasons that do
not echo the header or payload. A peer that previously sent a signed or otherwise
nonconforming header must send four hexadecimal digits before retrying.
Git discovery also preserves protocol classification for lengths 0001–0003,
missing or partial required headers and truncated payloads. The same discovery
classification reaches clone, fetch, pull, ls-remote and push. Check the remote
Git service or proxy response. Their existing structured error fields remain;
push retains its own protocol hint and the other commands retain theirs.
Flush 0000, empty-data 0004 and maximum-length ffff frames keep their existing
meaning. Ordinary network errors and timeouts retain their existing categories.
An empty fetch data stream before any complete pack remains a network failure;
EOF after a completed pack keeps the existing success behavior. The SSH host-trust
exception, captured-diagnostic limits and cleanup deadlines described above remain.
Empty-repository discovery framing
An HTTP(S) advertisement that declares an empty repository still has all remaining
pkt-line frames checked. A malformed header, an unsupported length 1..3, or a truncated
payload after the zero object ID returns LBR-NET-002 (exit 128), with a fixed
reason that does not echo the remote bytes. It is no longer reported as a
successful empty response. Check the remote Git service or proxy response before
retrying. Valid empty repositories, supported SHA-1/SHA-256 advertisements,
existing command hints and structured error fields retain their behavior.