Allow Git client server communication to exchange promisor remote information
# Summary
Allowing for Git client and server to exchange information through the protocol. This opens up many possibilities.
A new "promisor-remote" protocol capability has been implemented in several steps:
1. **Client and server can agree on using a common promisor remote** ([#421](https://gitlab.com/gitlab-org/git/-/issues/421), [#509](https://gitlab.com/gitlab-org/git/-/issues/509), [#332](https://gitlab.com/gitlab-org/git/-/issues/332)) - :white_check_mark: Released in `Git v2.49.0` (March 2025). The server can advertise a name and URL for each promisor remote.
2. **Server can pass a token and a filter to the client** ([#422](https://gitlab.com/gitlab-org/git/-/issues/422)) - :white_check_mark: Released in `Git v2.52.0` (November 2025). The server can additionally advertise a filter and a token for each promisor remote.
3. **Client can store and use the token and filter** ([#623](https://gitlab.com/gitlab-org/git/-/issues/623)) - :white_check_mark: Merged to 'next', pending release. A new `promisor.storeFields` config variable and an `auto` mode for `git clone --filter=<filter-spec>` / `git fetch --filter=<filter-spec>` allow the client to use information from the server without much configuration, as long as the promisor remote is already configured on the client.
4. **Server can tell client which new promisor remote to use** ([#423](https://gitlab.com/gitlab-org/git/-/issues/423)) - :construction: Remaining work. The client still cannot accept new promisor remote URLs from the server if they are not already configured locally. This has been postponed due to security concerns, and requires designing secure mechanisms (e.g. URL prefix allowlists) to control which server-advertised remotes the client trusts.
### Business case
One of the most important problems that Git has in the context of monorepos is the introduction of binary files. While tools like Git LFS exist, they aren't a great user experience and require third-party tooling. Furthermore, Git LFS cannot be used to strip binary files out of the history of Git and move them elsewhere.
The introduction of a native replacement for Git LFS will allow us to reap benefits on the client- and server-side:
- Clients can fetch objects on demand more readily, without requiring Git LFS and without requiring history rewrites.
- Servers can offload blobs to secondary (and cheaper) storage and serve them via CDNs.
These are necessary building blocks to make Git repositories ready to host large binary files as part of their commit history and will thus open up new industries that heavily rely on binary files. Furthermore, offloading large binary files to secondary storage may allow us to significantly reduce cost and reduce load on the Gitaly nodes, thus ensuring that GitLab.com can scale.
### Exit criteria
The server can advertise a promisor remote's name, URL, filter and token, to the client. The client can use the URL and filter it didn't know about to fetch objects at clone time from the remote.
### Status
<!-- STATUS NOTE START -->
## Status 2026-07-16
:clock1: **total hours spent this week by all contributors**: 24
:tada: **achievements**:
- Released as part of Git v2.49.0 on March 14, 2025:
[The server can pass a name and an URL to the client for each promisor remote it wants to advertise.](https://lore.kernel.org/git/20250218113204.2847463-1-christian.couder@gmail.com/)
- Released as part of Git v2.52.0 on Nov 17, 2025:
[The server can additionally pass a filter and a token for each promisor remote it wants to advertise.](https://lore.kernel.org/git/20250908053056.956907-1-christian.couder@gmail.com/)
- Released as part of Git v2.54.0 on April 20, 2026:
[A `promisor.storeFields` config variable and an `--filter=auto` mode for `git clone` and `git fetch`](https://lore.kernel.org/git/20260216132317.15894-1-christian.couder@gmail.com/) allow a client to access promisor remotes without much configuration by just using the information they get from the server.
:issue-blocked: **blockers**:
- A few months ago I sent [a 16 patch long series](https://lore.kernel.org/git/20260323080520.887550-1-christian.couder@gmail.com/) implementing a new `promisor.acceptFromServerUrl` configuration variable to allow clients to accept new promisor remotes (see https://gitlab.com/gitlab-org/git/-/work_items/423). In the reviews of that series, it was suggested that I split the series into a preparatory series and a feature series (that has most of the new features).
- The [v2 of the preparatory series](https://lore.kernel.org/git/20260407115243.358642-1-christian.couder@gmail.com/) with 10 patches, mostly small fixes, refactorings and cleanups [has just been merged to 'master'](https://gitlab.com/gitlab-org/git/-/commit/a19de4d24a5e62c092a0be809b6f81de87da3691).
- The [v4 of the feature series](https://lore.kernel.org/git/20260527140820.1438165-1-christian.couder@gmail.com/) has just been merged to 'master'.
- This week I continued working on the GIT_NO_LAZY_FETCH issue:
Right now for security reasons when a server cannot lazy fetch when it's a partial clone unless the GIT_NO_LAZY_FETCH environment variable is set to 0.
I was working on a new server-side config knob `uploadpack.allowLazyFetch = false | fromAccepted | true` which could alleviate that. The `fromAccepted` option would make it lazy fetch only from promisor remotes the client accepted via the `promisor-remote` protocol capability. But I realized that it would be much simpler for now to just introduce the new `fromAccepted` option to the `GIT_NO_LAZY_FETCH` env variable, leaving the new `uploadpack.allowLazyFetch` config variable for future work.
- So I reorganized my work and sent [a small patch series with the reduced scope](https://lore.kernel.org/git/20260710085137.4171240-1-christian.couder@gmail.com/) last week. This week brian carlson [replied against my patch series](https://lore.kernel.org/git/alFM-4FJQfaEjyju@fruit.crustytoothpaste.net/) for security reasons. I replied to him and I am now working on [a v2 that will address his concern](https://gitlab.com/gitlab-org/git/-/merge_requests/608). I have yet to add tests.
- I have a two week long vacation starting this evening. So I won't update this epics soon.
- The fact that the Git team is being reorganized and most team members are now focusing on the Scaling Git effort means that a big share of the regular team work is falling on @toon and me. So that it's difficult to get reviews from team members.
:arrow_forward: **next**:
- Maybe investigate the case where a server could advertised better connected promisor remotes even if it has all the objects. Another possibility is to implement the `uploadpack.allowLazyFetch` config variable but it looks complex for not much gain. Or we could perhaps just close this epic.
_Copied from https://gitlab.com/groups/gitlab-org/-/epics/15972#note_3564267076_
<!-- STATUS NOTE END -->
epic