summaryrefslogtreecommitdiff
path: root/docs/fetch-cmd.md
blob: 32fa8d1566b81510ec9e5bd0ef3c1c6cdf1db4de (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# Fetch Command Contract

The `repo.fetchcmd` configuration allows specifying a custom command to be
executed during `repo sync` to fetch objects, instead of using standard
`git fetch`. This is particularly useful in environments with virtualized
filesystems or lazy checkouts where fetching metadata and downloading file
contents should be decoupled.

## Configuration

To use this feature, set the following in `.repo/manifests.git/config`:
```ini
[repo]
	fetchcmd = "your custom command here"
	uselocalgitdirs = true
```
Setting `repo.fetchcmd` **requires** `repo.uselocalgitdirs` to be set to `true`.

## Environment Variables

The custom command is executed in a subshell populated with standard
project-context environment variables. For details on standard variables (such
as `REPO_PROJECT`, `REPO_PATH`, `REPO_PROJECT_FETCH_URL`, etc.), see the
Environment section in `repo help forall` or `subcmds/forall.py`.

The following environment variable is specific to `repo.fetchcmd`:

*   `REPO_TREV`: The target revision resolved to a full commit hash.

## Contract

### Postconditions on exit 0

After the fetch command exits with status 0, `repo` expects the following
postconditions to be met:

1.  `git cat-file -e REPO_TREV` succeeds (the commit must exist in the object
    store).
2.  The mapped local tracking ref (e.g. `refs/remotes/REPO_REMOTE/<branch>`
    for a branch revision, or the tag ref itself for a tag) must point to
    `REPO_TREV`.
3.  `FETCH_HEAD` must point to `REPO_TREV`.
4.  The commit graph from `REPO_TREV` must be reachable far enough to compute
    merge bases with local branches.

### Invariants

*   The command should be idempotent; fetching the same `REPO_TREV` twice should
    be a no-op.
*   Only `FETCH_HEAD` and `refs/remotes/*` should be modified to preserve
    `repo sync --network-only` semantics. `HEAD` and local branches must not be
    touched by the fetch command.
*   Dirty worktree state must be preserved.
*   The command is **not** executed for `MetaProject`s (i.e. the internal `repo`
    repository itself at `.repo/repo` and the `manifests` repository at
    `.repo/manifests`).

### Failure

*   A non-zero exit status aborts the project's sync, and the command's stderr
    is surfaced to the user.
*   `repo` verifies the tracking ref and target reachability after exit 0. Any
    mismatch is treated as a failure.