Skip to content

Commit dfdf577

Browse files
vapierLUCI
authored andcommitted
docs: smart-sync: split out & expand details
The existing documentation on smart-sync behavior is a bit light on details, and out of date wrt what the code actually does. Start a dedicated document and fill it out more. Change-Id: I1a8a3ac6edf9291d72182ad55db865035d9b683e Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/450002 Commit-Queue: Mike Frysinger <[email protected]> Tested-by: Mike Frysinger <[email protected]> Reviewed-by: Josip Sokcevic <[email protected]>
1 parent 747ec83 commit dfdf577

File tree

3 files changed

+131
-20
lines changed

3 files changed

+131
-20
lines changed

docs/manifest-format.md

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -231,26 +231,7 @@ At most one manifest-server may be specified. The url attribute
231231
is used to specify the URL of a manifest server, which is an
232232
XML RPC service.
233233

234-
The manifest server should implement the following RPC methods:
235-
236-
GetApprovedManifest(branch, target)
237-
238-
Return a manifest in which each project is pegged to a known good revision
239-
for the current branch and target. This is used by repo sync when the
240-
--smart-sync option is given.
241-
242-
The target to use is defined by environment variables TARGET_PRODUCT
243-
and TARGET_BUILD_VARIANT. These variables are used to create a string
244-
of the form $TARGET_PRODUCT-$TARGET_BUILD_VARIANT, e.g. passion-userdebug.
245-
If one of those variables or both are not present, the program will call
246-
GetApprovedManifest without the target parameter and the manifest server
247-
should choose a reasonable default target.
248-
249-
GetManifest(tag)
250-
251-
Return a manifest in which each project is pegged to the revision at
252-
the specified tag. This is used by repo sync when the --smart-tag option
253-
is given.
234+
See the [smart sync documentation](./smart-sync.md) for more details.
254235

255236

256237
### Element submanifest

docs/smart-sync.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# repo Smart Syncing
2+
3+
Repo normally fetches & syncs manifests from the same URL specified during
4+
`repo init`, and that often fetches the latest revisions of all projects in
5+
the manifest. This flow works well for tracking and developing with the
6+
latest code, but often it's desirable to sync to other points. For example,
7+
to get a local build matching a specific release or build to reproduce bugs
8+
reported by other people.
9+
10+
Repo's sync subcommand has support for fetching manifests from a server over
11+
an XML-RPC connection. The local configuration and network API are defined by
12+
repo, but individual projects have to host their own server for the client to
13+
communicate with.
14+
15+
This process is called "smart syncing" -- instead of blindly fetching the latest
16+
revision of all projects and getting an unknown state to develop against, the
17+
client passes a request to the server and is given a matching manifest that
18+
typically specifies specific commits for every project to fetch a known source
19+
state.
20+
21+
[TOC]
22+
23+
## Manifest Configuration
24+
25+
The manifest specifies the server to communicate with via the
26+
the [`<manifest-server>` element](manifest-format.md#Element-manifest_server)
27+
element. This is how the client knows what service to talk to.
28+
29+
```xml
30+
<manifest-server url="https://example.com/your/manifest/server/url" />
31+
```
32+
33+
If the URL starts with `persistent-`, then the
34+
[`git-remote-persistent-https` helper](https://github.com/git/git/blob/HEAD/contrib/persistent-https/README)
35+
is used to communicate with the server.
36+
37+
## Credentials
38+
39+
Credentials may be specified directly in typical `username:password`
40+
[URI syntax](https://en.wikipedia.org/wiki/URI#Syntax) in the
41+
`<manifest-server>` element directly in the manifest.
42+
43+
If they are not specified, `repo sync` has `--manifest-server-username=USERNAME`
44+
and `--manifest-server-password=PASSWORD` options.
45+
46+
If those are not used, then repo will look up the host in your
47+
[`~/.netrc`](https://docs.python.org/3/library/netrc.html) database.
48+
49+
When making the connection, cookies matching the host are automatically loaded
50+
from the cookiejar specified in
51+
[Git's `http.cookiefile` setting](https://git-scm.com/docs/git-config#Documentation/git-config.txt-httpcookieFile).
52+
53+
## Manifest Server
54+
55+
Unfortunately, there are no public reference implementations. Google has an
56+
internal one for Android, but it is written using Google's internal systems,
57+
so wouldn't be that helpful as a reference.
58+
59+
That said, the XML-RPC API is pretty simple, so any standard XML-RPC server
60+
example would do. Google's internal server uses Python's
61+
[xmlrpc.server.SimpleXMLRPCDispatcher](https://docs.python.org/3/library/xmlrpc.server.html).
62+
63+
## Network API
64+
65+
The manifest server should implement the following RPC methods.
66+
67+
### GetApprovedManifest
68+
69+
> `GetApprovedManifest(branch: str, target: Optional[str]) -> str`
70+
71+
The meaning of `branch` and `target` is not strictly defined. The server may
72+
interpret them however it wants. The recommended interpretation is that the
73+
`branch` matches the manifest branch, and `target` is an identifier for your
74+
project that matches something users would build.
75+
76+
See the client section below for how repo typically generates these values.
77+
78+
The server will return a manifest or an error. If it's an error, repo will
79+
show the output directly to the user to provide a limited feedback channel.
80+
81+
If the user's request is ambiguous and could match multiple manifests, the
82+
server has to decide whether to pick one automatically (and silently such that
83+
the user won't know there were multiple matches), or return an error and force
84+
the user to be more specific.
85+
86+
### GetManifest
87+
88+
> `GetManifest(tag: str) -> str`
89+
90+
The meaning of `tag` is not strictly defined. Projects are encouraged to use
91+
a system where the tag matches a unique source state.
92+
93+
See the client section below for how repo typically generates these values.
94+
95+
The server will return a manifest or an error. If it's an error, repo will
96+
show the output directly to the user to provide a limited feedback channel.
97+
98+
If the user's request is ambiguous and could match multiple manifests, the
99+
server has to decide whether to pick one automatically (and silently such that
100+
the user won't know there were multiple matches), or return an error and force
101+
the user to be more specific.
102+
103+
## Client Options
104+
105+
Once repo has successfully downloaded the manifest from the server, it saves a
106+
copy into `.repo/manifests/smart_sync_override.xml` so users can examine it.
107+
The next time `repo sync` is run, this file is automatically replaced or removed
108+
based on the current set of options.
109+
110+
### --smart-sync
111+
112+
Repo will call `GetApprovedManifest(branch[, target])`.
113+
114+
The `branch` is determined by the current manifest branch as specified by
115+
`--manifest-branch=BRANCH` when running `repo init`.
116+
117+
The `target` is defined by environment variables in the order below. If none
118+
of them match, then `target` is omitted. These variables were decided as they
119+
match the settings Android build environments automatically setup.
120+
121+
1. `${SYNC_TARGET}`: If defined, the value is used directly.
122+
2. `${TARGET_PRODUCT}-${TARGET_RELEASE}-${TARGET_BUILD_VARIANT}`: If these
123+
variables are all defined, then they are merged with `-` and used.
124+
3. `${TARGET_PRODUCT}-${TARGET_BUILD_VARIANT}`: If these variables are all
125+
defined, then they are merged with `-` and used.
126+
127+
### --smart-tag=TAG
128+
129+
Repo will call `GetManifest(TAG)`.

subcmds/sync.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,6 +1502,7 @@ def _SmartSyncSetup(self, opt, smart_sync_manifest_path, manifest):
15021502
if manifest_server.startswith("persistent-"):
15031503
manifest_server = manifest_server[len("persistent-") :]
15041504

1505+
# Changes in behavior should update docs/smart-sync.md accordingly.
15051506
try:
15061507
server = xmlrpc.client.Server(manifest_server, transport=transport)
15071508
if opt.smart_sync:

0 commit comments

Comments
 (0)