mirror of
https://gerrit.googlesource.com/git-repo
synced 2026-07-16 05:36:59 +00:00
sync: Implement fetchcmd for standard Git layouts
Introduce support for `repo.fetchcmd` configuration, allowing users to specify a custom command to fetch project data instead of `_RemoteFetch`. When `repo.fetchcmd` is specified, `repo` will execute it instead of `_RemoteFetch` during the network half of sync. Note that `repo.fetchcmd` requires `repo.uselocalgitdirs` to be enabled. The command is executed in a subshell with project-context environment variables, including the new `REPO_TREV` (target revision resolved to a commit hash) and `REPO_PROJECT_FETCH_URL`. After execution, `repo` verifies that the target commit is available and that the tracking ref and FETCH_HEAD are correctly updated. Tested with: ``` > ~/git-repo/repo init -u https://android-review.googlesource.com/platform/manifest \ --repo-url file:///usr/local/google/home/gavinmak/git-repo \ --groups developers \ --no-repo-verify \ --use-local-gitdirs ... > git config --file .repo/manifests.git/config repo.fetchcmd 'mkdir -p $REPO_PATH && cd $REPO_PATH && if [ ! -d .git ]; then git init && git remote add aosp $REPO_PROJECT_FETCH_URL; fi && git fetch aosp $REPO_TREV && git reset --hard $REPO_TREV && mkdir -p .git/refs/remotes/aosp && echo $REPO_TREV > .git/refs/remotes/aosp/main && echo $REPO_TREV > .git/FETCH_HEAD' > ~/git-repo/repo sync -j32 warning: repo is not tracking a remote branch, so it will not receive updates; run `repo init --repo-rev=stable` to fix. You are currently enrolled in Git submodules experiment (go/android-submodules-quickstart). Use --no-use-superproject to override. Syncing: 100% (4/4), done in 1m15.686s Finalizing sync state... repo sync has finished successfully. ``` Bug: 513329573 Change-Id: I754d3f3c78e86fdeee1a72115297a75b571bc497 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/583883 Reviewed-by: Becky Siegel <beckysiegel@google.com> Tested-by: Gavin Mak <gavinmak@google.com> Commit-Queue: Gavin Mak <gavinmak@google.com>
This commit is contained in:
committed by
gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
e7cac4bca6
commit
ead4b2d7aa
@@ -0,0 +1,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.
|
||||
Reference in New Issue
Block a user