Overview of Repo
mainrepo command is a standalone executable Python script.repository·main·Indexed 19 days ago
https://github.com/gerritcodereview/git-repoA Python-based tool built on top of Git to manage multiple Git repositories and automate development workflows, commonly used in large-scale projects like Android. It provides a wrapper to handle collections of repositories via manifests, custom fetch commands, and integrated Gerrit review interactions.
repo command is a standalone executable Python script.The .repo/ directory contains the internal state of your repo client checkout. Key components include:
config: Per-repo client checkout settings in git-config format..repo_config.json: A JSON cache of the config file for faster processing.repo/: A git checkout of the repo project itself, used for self-updating..repo_fetchtimes.json: Records fetch times used by repo sync..repo_localsyncstate.json: Used by repo sync to detect partial tree syncs.manifests/: A git checkout of the manifest project.manifests.git/: A bare checkout of the manifest project.manifest.xml: The active manifest file used by repo (often a symlink to a file in manifests/).local_manifests/: Directory for user-authored manifest fragments used to tweak the manifest.projects/: Bare checkouts of every project synced by the manifest.project-objects/: Shared git objects to allow multiple checkouts of the same remote repo to save space.modules/ & subproject-objects/: Similar to projects/ and project-objects/ but for git submodules.worktrees/: Used when git worktree is enabled.Smart Syncing allows repo sync to fetch specific, known source states from a remote server instead of just tracking the latest revisions of all projects in a manifest.
Instead of blindly fetching the latest code, the client sends a request to a manifest server via an XML-RPC connection. The server responds with a specific manifest (typically specifying exact commits for every project) that matches the user's requested state (e.g., a specific release or build). This ensures a reproducible local build environment.
Repo maintains user-specific configuration and state in a .repoconfig/ directory. By default, this is located in the user's home directory, but the location can be customized by setting the REPO_CONFIG_DIR environment variable.
.repoconfig/config: Per-user settings using the standard [git-config] file format..repoconfig/keyring-version: A cache file used to check if the gnupg subdirectory contains the same keys as the repo launcher, preventing slow, constant GPG executions..repoconfig/gnupg/: An isolated GnuPG internal state directory used when repo runs gpg, ensuring it does not interfere with the user's standard ~/.gnupg/ directory.Repo maintains JSON caches of configuration files to improve processing speed:
.repoconfig/.repo_config.json: A JSON cache of the .repoconfig/config file..repo_.gitconfig.json: A JSON cache of the .gitconfig file.A repo manifest file (typically default.xml) is an XML document that defines the collection of Git repositories to be managed. It follows a specific DTD that allows for defining remotes, default settings, submanifests, and individual projects.
Key behaviors:
x-* namespace to avoid collisions with future repo updates.project can be nested to represent Git submodules, inheriting attributes from their parents unless overridden.extend-project and remove-project to modify an existing manifest without replacing it entirely.<!DOCTYPE manifest [
<!ELEMENT manifest (notice?, remote*, default?, manifest-server?, submanifest*?, remove-project*, project*, extend-project*, repo-hooks?, superproject?, contactinfo?, include*)>
<!-- ... other element definitions ... -->
]>
<manifest>
<!-- Manifest content goes here -->
</manifest>If you are implementing a custom fetch command, your command must adhere to the following contract to ensure repo sync works correctly:
After your command exits with status 0, repo requires:
git cat-file -e REPO_TREV).refs/remotes/REPO_REMOTE/<branch> or the tag ref) must point to REPO_TREV.FETCH_HEAD must point to REPO_TREV.REPO_TREV must be reachable enough to compute merge bases with local branches.REPO_TREV twice should be a no-op.FETCH_HEAD and refs/remotes/*. Do not touch HEAD or local branches. This preserves repo sync --network-only semantics.MetaProjects (the internal repo repository at .repo/repo or the manifests repository at .repo/manifests).stderr to the user.repo detects a mismatch in tracking refs or target reachability after your command exits with 0, it will treat it as a failure.When developing hooks, keep the following runtime characteristics in mind:
os.chdir to move into a specific project directory.sys.exit() with a non-zero exit code.sys.path is modified so that the top of the repohooks directory comes first, allowing easy imports of local modules within the hooks project.https:// manifests, this happens once. For http:// manifests, users are prompted whenever the hooks project is updated.Projects using [repo hooks] run on independent schedules. Because it is not possible to detect which Python version the hooks were written or tested against, repo always imports and executes them using the active Python version.
If the active Python version is too new for the hooks, the responsibility for updating the hooks lies with the hooks maintainer.
A repo manifest defines the structure of a repo client, specifying which directories are visible and their corresponding Git source locations.
A manifest is implemented as a bare Git repository containing a single default.xml file at its top level. Because manifests are stored in Git repositories, they are version-controlled; when a user runs repo sync, the client automatically fetches updates to the manifest from the remote repository.
Repo allows you to hook specific runtime stages (like pre-upload or post-sync) with custom Python modules.
Core Workflow:
repo init) specifies which project contains the hooks and which stages they are enabled for.main function.These hooks are ideal for running linters, checking code formatting, or executing unit tests before allowing operations like uploading commits to Gerrit.
The repo launcher is an independent script designed to support older Python versions without restricting the main codebase.
If the launcher detects that the current Python version is too old to run the main codebase, it attempts to re-execute itself using a newer Python interpreter via standard pythonX.Y interpreter names.
If your default Python interpreters are too old to run the launcher even when newer versions are installed, you can:
repo launcher's shebang to match your environment.repo launcher (note: old launchers are not guaranteed to work with current versions of repo, and bug reports using old launchers will not be accepted).Repo 2.4+ supports Git worktrees, which allows Repo to create client checkouts that do not require symlinks. This is useful on Windows because it removes the need for Administrator access to sync code. To use this feature, opt in by passing the --worktree flag during the repo init command.
Note: This is an experimental feature. Maintain backups and report any bugs.
repo init --worktree