Repository navigation
The latest release of Lore, Epic Games' next-generation open source version control system.
Quickstart | Design | Documentation | Discord
Quick Install
Windows
irm https://raw.githubusercontent.com/EpicGames/lore/main/scripts/install.ps1 | iex
macOS / Linux
curl -fsSL https://raw.githubusercontent.com/EpicGames/lore/main/scripts/install.sh | bash
Release Notes
Changes since v0.10.1.
Breaking changes
- C API: the new
LORE_EVENT_FILE_AUDITevent adds a member tolore_event_t; rebuild against the newlore.h [environment.endpoint] user_urlnow names alore.user.v1.UserService(UserGet,UserFind) instead of theUrcAuthApiGetUserInfo/GetUserIdcalls. Withuser_urlset, the server also lists repositories there by default ([server.auth] repository_catalog = "user_service") and registers the repositories it creates and deletes there instead of callingRebacApi. Without it, clients askauth_urlas before- A client and the Lore service it relays to must come from the same build (message protocol version 2); restart the service after upgrading
- Data is verified by the trust of its source (ADR-00023): local store reads no longer verify hashes, and data fetched from a remote is verified on receipt unless the remote is trusted (
--trust-remote). C API:skip_verifyonlore_storage_open_args_tis now an alias oftrust_remoteand skips verifying fetched data only - C API:
lore_branch_merge_start_args_tgainslink_pathsandlink_messages, changing its size; rebuild against the newlore.h. A zero-initialized struct keeps today's behavior lore-server: refuses to start if[server.auth] resource_id_templateor[server.auth.oidc]resource_template/scope_templatelacks{id}, since such a template let one grant match every partition
Features
lore file audit <path>shows, for each line of a file, the revision that last changed it, grouped into ranges of consecutive lines (C API:lore_file_audit/lore_file_audit_async)--trust-remote(C API:trust_remoteonlore_global_args_t) skips hash verification of fetched data, keeping only a size check, for machines inside the remote's own infrastructure such as build servers. C callers must zero the whole struct, padding included, or stray bytes turn it on- C API:
fragmentsonlore_storage_get_resolved_item_tdelivers content piece by piece as stored (LORE_EVENT_STORAGE_GET_FRAGMENT), leaving decoding and verification to the reader, which can keep payloads compressed lore auth loginagainst an OIDC issuer uses the OAuth 2.0 device authorization grant (RFC 8628), opening the verification URL in the browser or printing it with--no-browser;--token-type <TYPE> --token <TOKEN>logs in with an existing token through RFC 8693 token exchange. Partition and repository operations send the access token, or a per-partition token when the server advertisesresource_template/scope_template. ID tokens are never stored or sent; refresh and client credentials grants aren't implemented yet- The user identity is read from a token by the same rule on client and server: the
identityclaim (orhttps://lore.org/claims/identity), elsesub. Tokens with an empty or non-string identity are refused, and[server.auth] identity_claimis removed lore branch mergeandlore branch merge starttake--link-message <PATH> <MESSAGE>, aslore commitdoeslore clone --offline/--cacheprepares a clone so staging and committing work without a connectionlore service statusreports the status of the running Lore serviceLORE_STORE_RETAIN=1keeps a process's stores loaded between repository calls, without holding their locks, forstore_keep_alive_seconds(default 10). While it's set, don't share a store directory with processes of an earlier buildlore-server:[server.http] health_only = trueserves only/health_checklore-servermetrics: gRPC requests recordrpc.server.handler.duration, excluding request upload and pre-body work such as authorization, andBranchPushrecords its fragment verification load underlore.branch_pushcontrib/bazel/: a Bazel remote execution server (Remote Execution API v2) keeping its action cache and content-addressable storage in Lore partitions
Fixes & Improvements
lore sync --resetreplaces a directory with a file at the same path instead of failing with "Is a directory", and syncs, branch switches, resets, merges and view changes report each deleted file and directory viaLORE_EVENT_REVISION_SYNC_FILE. Files and directories named.urcor.lore, in any case, are ignored by every commandlore commitandlore clonereport the error that stopped them instead ofRecursion task failed, and a failed clone no longer printsClone complete(C API:LORE_EVENT_REPOSITORY_CLONE_ENDis sent only on success)lore status:--scanof many paths runs in parallel, files are listed in stable path order, and modified files are no longer missed after a scan that dropped a reverted add or after a same-size re-save- Merges of divergent history (such as a sync with new local and remote revisions):
lore file historyattributes remote changes correctly, remote additions and earlier remote changes are kept, committing no longer fails in some cases, and the branch is reported ahead of the remote instead of diverged afterwards - Layers: committing a staged layer works when the parent tree holds only unstaged dirty changes, and several commands no longer copy the current revision's metadata, such as its reviewer, onto the next revision
- Merge conflicts: a branch's change to a file is no longer dropped without a conflict in some add-after-delete cases, and resolving to one side no longer uses memory in proportion to the size of the tree
- Links: committing through a link pinned at a merge revision no longer records a spurious merge, staging inside a nested link more than once no longer pushes intermediate states, and
lore commit --link-messageaccepts any spelling of the link path lore dirtyinside a link, or on its mount, marks the change in the linked repository, solore statusand staging pick it up without a scan- Lore service: commands run with the caller's configuration and credentials,
lore_storage_put/lore_storage_get(and their_resolvedvariants) work through the service, unreadable shared stores or instances are skipped at startup, and on Linux and macOS two services started at once no longer both run - Auth: the CLI sends tokens only to hosts named in their
root_domainsoraudclaims, no longer to theisshost except for token exchange. With[server.auth] resource_claimset, repository lookups by name or id answer any verified caller, so clone,lore link add,lore layer add,repository infoandrepository deleteno longer fail as not found before the caller holds a grant - Server write checks: pushing to a protected branch requires the
push-protectedaction and theis_service_accountclaim no longer bypasses protection, so grantpush-protectedto mirroring accounts first. GenericMutableStore/MutableCompareAndSwaprequests can no longer write repository metadata, branch metadata or branch latest pointers; useRepositoryMetadataSet,BranchMetadataSetandBranchPush RevisionList: listing from a revision above the branch's latest no longer crashes the server, and paging through older history on a deep branch no longer times out withCancelled- Pushing and committing: some large files no longer fail to commit or push, and a retried push or a gRPC push copying the same content to several files no longer fails with a missing fragment
- Verification: caches, prefetches and immutable store queries verify fetched data unless the remote is trusted, fetching again once after asking the server to repair it, and corrupt local data is fetched again and replaced instead of crashing an unverified read
- Reads: streaming reads and reads into files enforce the content size limit, a corrupt fragment list with out-of-order offsets fails the read instead of returning wrong data, and reads of fragmented content do less redundant work
- Fetching: concurrent reads of the same missing content download it once, and caching runs at most 512 fetches at once per remote connection (
LORE_CACHE_GETS), so reads a command needs right away don't queue behind it lore-serverwith aremotestore verifies data fetched from the backend and asks it to repair failures, refuses data in a codec it's built without (such as Oodle), size-checks data from replicas and peers, and no longer crashes on a truncated replica response- Oodle: the local store's Oodle migration finishes sooner, and a build without Oodle replaces such data with the remote's re-encoded copy, or reports
NotSupportedwhere there's no remote copy - Commands start faster, as opening a repository lists each store's index once;
lore repository createsyncs to disk only with--sync-data - Fix a deadlock between processes using one repository, such as the Lore service and a storage handle; stores are now locked only while in use, so idle handles no longer block other processes
- Local store durability: transient I/O errors, failed or interrupted flushes, obliterates and index reorganizations no longer lose data, bring back removed entries or serve another file's data, and background index flushes now follow every change
- A local store whose
versionfile can't be read fails to open instead of re-migrating on every open; an affected store recovers at its next command connected to the remote - Obliterate in local stores is saved to disk before the data is zeroed and waits for reads in progress, and obliterated content no longer comes back when stored again under another context or re-encoded
- Compaction does far less disk work and no longer stalls server stores for minutes; client stores never evict local-only data, and
lore repository gcno longer swapsmax_sizeandmax_capacity - Storage sessions: handles reuse one server session per partition, so long-running processes are no longer refused every later call, and an unauthorized session is retried once with fresh authorization
- Reconnects: storage handles and servers' remote stores reconnect after a failed connection, with a backoff of up to 30 seconds, QUIC streams that stop carrying requests reconnect instead of hanging, and reads and uploads use all the connections
--max-connectionsallows - QUIC: the vendored
quinn-protomoves to 0.11.19, fixing CVE-2026-25800 (unauthenticated remote memory exhaustion) and other upstream memory-exhaustion, stream-limit, Retry-token and path MTU issues - QUIC throughput: congestion control and stream ordering fixes, and the client asks for a larger UDP receive buffer; on Linux, set
net.core.rmem_maxto524288or more to allow it - C API: a call reading into
data_outthat stops part way no longer writes the caller's buffer after completion.data_outmust stay valid until completion, andlore_shutdownis safe only once every call has completed
Release Assets
Important
These can be downloaded under the "Assets" section below.
Installer
lore-setup- Lore CLI Windows installer
Binaries
lore- Lore CLIloreserver- Lore Serverliblore- Lore Shared Library
Headers
lore.h- Single header forliblore(packged withliblore)
Supported Platforms
- Windows x84_64
- macOS AArch64
- Linux x86_64
- Linux AArch64 (for Graviton/Neoverse 512-tvb only)
Lore Desktop Client
Important
Lore Desktop Client is available as binaries only, download the installer for your platform here:
- Windows: Lore-Desktop-Setup-x64.exe
- macOS: Lore-Desktop-arm64.dmg
- Linux (Ubuntu 24.04): lore-desktop_amd64.deb
- Linux (AppImage): Lore-Desktop-x86_64.AppImage