What is a repo?
Repo is a tool developed by Google for managing Android repositories. Repo uses Python to encapsulate git to a certain extent. It is not used to replace git. It simplifies the management of multiple Git repositories. The version library managed by repo needs to use the git command to operate. Therefore, before using the repo tool, please ensure that git is installed.
Why use repo?
After the project is modularized/componentized, each module is also separated from the main project as an independent Git repository, and each module manages its own version. The Android source code refers to many open source projects. Each sub-project is a Git repository, and each Git repository has many branch versions. In order to facilitate the unified management of the Git repositories of each sub-project, an upper-level tool is needed for batch processing, so repo was born. .
Repo will also create a Git warehouse to record which branch the Git warehouse of each sub-project under the current Android version is in. This warehouse is usually called: manifest warehouse (list library).
repo download and install
Download address: https://mirrors.tuna.tsinghua.edu.cn/git/git-repo , name the downloaded file repo, and place it under the directory contained in the PATH environment variable, for example, it can be placed /usr/local/bin
in the directory ( The following introductions are all in /usr/local/bin
the directory as an example).
Alternatively, download directly using the curl command:
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > /usr/local/bin/repo
Finally, modify the execution permission of the repo file: chmod 777 /usr/local/bin/repo
.
In fact, the downloaded repo file is just a boot script written in Python (Google calls it Repo launcher, which is essentially a python script that can be opened with vim), and the complete repo (that is, the main part of repo) has not been downloaded yet. .
repo help
View the help description of repo, which lists the subcommands supported by repo and a brief introduction of each subcommand.
If you need to view the detailed introduction of a specific subcommand, repo help <command>
just execute the command. For example View repo init
help can be entered repo help init
.
As mentioned in the previous section, the downloaded repo is just a boot script. The complete repo tool has not been downloaded yet, as shown in the figure below. At this time, you can only see
repo help
andinit
twohelp
subcommands, and the help information will also prompt repo It has not been installed yet and needs to berepo init
installed. (Need to pay attentionrepo init
to the need to follow the parameters, which will berepo init
introduced separately later)
After executing and
repo init
downloading the complete repo tool,repo help
you will see more subcommands of repo if you execute it again. As shown below:
repo version
Command format:
repo version
View the version of the repo
repo selfupdate
Command format:
repo selfupdate
For updates to the repo itself. If a new version of the repo exists, this command will upgrade the repo to the latest version. Usually this action will be done automatically when repo sync, so the end user does not need to do it manually.
Common options:
--no-repo-verify
: Do not verify the repo source code.
repo init
repo init command
Command format:
repo init [options] [manifest url]
For example:
repo init -u manifest_git_path -m manifest_file_name -b branch_name --repo-url=repo_url --no-repo-verify
Command effect: First, a directory
is generated in the current directory , and then a copy of the source code of repo is cloned to the next directory, which stores other repo subcommands, that is, the main part of repo. Then clone the list library from the warehouse address to the and directory. At the same time , the directory also includes the content of the manifest warehouse (list library).repo
.repo/repo
manifest_git_path
.repo/manifests
.repo/manifests.git
.repo
Common options:
-u
: Specify the Git access path of the Manifest library. the only essential option-m
: Specify the Manifest file to use. If not specified, the default is the default.xml file-b
: Specifies to use a specific branch in the Manifest repository.--repo-url
: Specify the access path of the remote repoGit library of repo.--no-repo-verify
: Specifies not to verify the repo source code.--mirror
: Create a copy of the remote repository instead of the client working directory. This option is used to create repository mirrors. If this option is used, in the next steprepo sync
of synchronization, the local organization will be organized according to the source repository organization method, otherwise it will be reorganized and checked out to the local according to the method specified in manifest.xml
Modify the source code path to obtain repo
As mentioned above, the downloaded repo is just a boot script. When it is executed, the repo init
main part of the repo will be downloaded and stored .repo/repo
in the directory of the current directory.
Here will involve a question, where is the main part of the repo downloaded from? In fact, looking at the bootstrap script of repo (/usr/local/bin/repo), we can find that the main part of repo is https://gerrit.googlesource.com/git-repo
obtained from by default (that is, repo init
when the command is executed, no option is set --repo-url
), and this website needs to be accessed scientifically.
To solve this problem, you can use other mirror sources, such as Tsinghua source. There are many ways to implement it. Here are two ways for reference:
Method 1:
Add options every time you execute repo init--repo-url=https://gerrit-googlesource.lug.ustc.edu.cn/git-repo
Method 2: (recommended)
set environment variables REPO_URL
, for example:
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
Environment variables can be written in the startup script (eg, /etc/profile
)
Introduction to the .repo folder
After executing the command, a folder repo init
will be created in the current directory . .repo
Let's take a look at what's under the folder.
$ tree .repo -L 1
.repo
├── manifests
├── manifests.git
├── manifest.xml
└── repo
3 directories, 1 file
folder | describe |
---|---|
manifests | The content of the manifest warehouse (list library), that is, repo init the -u warehouse corresponding to the option |
manifests.git | .git The directory of the manifest warehouse (list library) |
manifest.xml | Indicates the currently effective Manifest file, that is, repo init the -m parameter corresponding to the option (the default is default.xml if there is no such option) |
repo | The body of the repo command, containing the latest repo command |
Manifest file introduction
The so-called manifest warehouse (list library) is actually a warehouse that stores manifest (list) files. In fact, it can be any warehouse, as long as there is a manifest file specified by the repo init
command option in the warehouse. The name of the manifest library is just a convention. It's just a way of writing.-m
manifest
The manifest warehouse generally has a default.xml file, which is the default manifest file.
manifest file format
The manifest file records the name, address, and branch information of each Git warehouse that this project depends on in the format of an XML file.
Let's take a practical example to see what the manifest file looks like
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote fetch="ssh://[email protected]/learn-repo" name="origin" review="http://xxx.xxx.xxx:8080"/>
<remote fetch="https://github.com" name="github" alias="origin"/>
<default remote="origin" revision="master" sync-j="4" />
<project name="build" path="build">
<linkfile dest="build.sh" src="build.sh"/>
</project>
<project name="docs" path="docs">
<copyfile dest="README.md" src="README.md"/>
</project>
<project name="third_party/openssl" path="third_party/openssl" revision="OpenSSL_1_1_1l" />
<project name="curl/curl" path="third_party/curl" remote="github" />
<project name="src" path="src" revision="release" />
</manifest>
1. remote element
There can be multiple remote elements, which are used when there are multiple git remote servers.
fetch
: Git URL prefix for all projects using this remote. The name of each project is appended to this prefix to form the actual URL used to clone the project. If the prefix of all projects using this remote is consistent with the prefix of the manifest warehouse, it can be used..
instead.name
: A unique short name for this manifest file. The name specified here is used as the remote name.git/config
in and is therefore automatically available for commands suchgit fetch
as ,git remote
, andgit pull
.git push
review
: Byrepo upload
the hostname of the Gerrit server the comment is uploaded to. This attribute is optional; if not specified,repo upload
it will have no effect .alias
: This attribute can be omitted. When this attribute is specified, it can override the name attribute to set the.git/config
remote name in each project. The alias attributes of different remote elements can be the same, for example, the alias attributes of different remote elements can be allorigin
.
2. default element
There can only be one default element.
remote
: If the project part does not specify remote separately, the default part will be used.revision
: If the project part does not specify revision separately, the default part will be used.sync-j
repo sync
: The number of parallel jobs used when synchronizing (when executing commands)sync_c
: If set to true, only the specified branch (specified by the revision attribute) will be synchronized, not all ref contentsync_s
: If set to true, subprojects of git will be synchronized
3. The project element
defines which sub-warehouses the project code consists of
name
:fetch
a relative path relative to the prefix specified in the remote sectionpath
: After downloading the code, the local relative path relative to the current pathrevision
: Refers to which revision the downloaded code should be checked out to. The revision here can be a commit id, branch name, or tag name, which are essentially commit ids. The default.xml usually uses the branch name as a revision, and you can download and checkout the latest code on the branch. The tag and/or commit id should be valid in theory, but it has not been extensively tested. If the revision uses a commit id, it must be followed by upstream, and the value of upstream is a branch name. If the revision part is omitted, it is equivalent to using the revision defined in the default part.remote
: The name of the previously defined remote element. If not provided, the value provided by the default element is used.
4. The copyfile element
is a child element of the project element, and each element describes a pair of src-dest files. When synchronizing (that is, repo sync
when executing the command), src
the file will be copied to dest
. Usually used in README or Makefile or other build scripts.
dest
: is the path relative to the current directory (execution repo init
and repo sync
command directory)
src
: is the relative path relative to the project path
5. The linkfile element
is similar to copyfile
, except that instead of copying, a soft link is established.
For more information about the format of the manifest file, you can see the relevant documentation under the repo init
root directory of the code after the command is successfully executed (Q: If you can’t write a manifest file, you can’t create a manifest library, so you can’t execute repo init. .repo/repo/docs
What to do? Answer: You can find an open source inventory library to execute repo init
, or go to github to download a copy of the source code of the repo). The easiest way is to go directly to the website https://gerrit-googlesource.proxy.ustclug.org/git-repo/+/HEAD/docs/manifest-format.md to view the help.
repo sync
Command format:
repo sync [<project>...]
After initializing a repo working directory, the next step is to synchronize the code. This command is used to download new changes and update the working files in the local environment. If you run it without any parameters repo sync
, the operation will synchronize the files of all projects (all projects refer to all project elements in the manifest file).
<project>
name
: The attribute or path
attribute value of the project element in the manifest file . This method can be used if only one or a few projects need to be synchronized.
After running repo sync
, the following will happen:
repo sync
Equivalent if the target project has never been syncedgit clone
. All branches in the remote repository are copied to the local project directory.- If the target project has already been synced, repo sync is equivalent to the following command:
wheregit remote update git rebase origin/<BRANCH>
<BRANCH>
is the currently checked out branch in the local project directory. If the local branch is not tracking a branch in the remote repository, no synchronization will occur for the corresponding project. - If
git rebase
the operation results in a merge conflict, then you need to use normal Git commands (eggit rebase --continue
) to resolve the conflict.
After repo sync runs successfully, the code in the specified project will be synchronized with the code in the remote code base.
Common options:
-d
: Switch the specified item back to the manifest revision. This option is helpful if the project currently belongs to a topic branch, but the manifest revision is only needed temporarily.-s
: Synchronize to a known-good version specified by the manifest-server element in the current manifest.-f
: Even if an item fails to sync, other items will continue to sync.-t
: Use the manifest file in the corresponding tag-m
: Manually specify which manifest file to use for the current operation--force-sync
: Forces overwriting existing git directories to point to different object directories, if desired. This action may result in data loss
repo start creates a topic branch
Command format:
repo start <newbranchname> [--all | <project>...]
Create and switch branches. The newly cloned code has no branches , repo start
but actually git checkout -b
encapsulates the commands.
Creates a specific branch for the specified project, or all projects (if used -all
), using the specified branch in the manifest file.
Common options:
<newbranchname>
The argument should briefly describe the change you are trying to make to the project.<project>
Specifies the projects that will participate in this topic branch.
Note:
.
is a very useful shorthand for representing items in the current working directory.
This instruction git checkout -b
is still very different from .
git checkout -b
Create a feature branch based on the current branch.repo start
is to create feature branches based on the branches set by the manifest file.
repo status
Command format:
repo status [<project>...]
View file status. For each specified project, compare the working tree with the staging area (index) and the last commit on this branch (HEAD). A summary line for each file is displayed where the three states differ.
To see only the status of the current branch, run repo status
. The system lists status information by project. For each file in a project, the system uses a two-letter code to identify it:
- In the first column, capital letters indicate differences between the staging area and the last commit state.
letter meaning describe - no change HEAD is the same as in the index A added does not exist in HEAD, but exists in the index M already edited exists in HEAD, but the file in the index has been modified D deleted present in HEAD but not in the index R renamed does not exist in HEAD, but the path of the file in the index has changed C copied does not exist in HEAD, has been copied from another file in the index T schema changed HEAD is the same as in the index, but the schema has changed U not merged HEAD is the same as in the index, but the schema has changed - In the second column, lowercase letters indicate the difference between the working directory and the index.
letter meaning describe - new/unknown HEAD is the same as in the index m already edited exists in the index, and also exists in the working tree (but modified) d deleted exists in the index, not in the working tree
After the two letters indicating status, the file name information is displayed. If there is a file with the same name, it will also display the file name before and after the change and the similarity of the file.
repo checkout
Command format:
repo checkout <branchname> [<project>...]
Switch branches. It is actually an encapsulation of the git checkout command, but it cannot take -b
parameters, so this command cannot be used to create a feature branch.
This command is equivalent to:repo forall [<project>...] -c git checkout <branchname>
repo branch
This command is equivalent to repo branches
the command format:
repo branches [<project>...]
Summarizes all currently available topic branches.
repo diff
Command format:
repo diff [<project>...]
View workspace file diffs. In fact, it is git diff
the encapsulation of the command, which is used to display the file differences under each project or the specified project workspace respectively. Use changes between commit and working directory git diff
to show significant differences.
repo stage
Command format:
repo stage -i [<project>...]
Add the file to the index table. In fact, it is git add --interactive
the encapsulation of the command, which is used to select the changes in each project to add to the staging area.
Common options:
-i
: Indicatesgit add --interactive
in the command--interactive
, giving an interface for the user to choose.
repo forall
repo forall [<project>...] -c <command> [<arg>...]
Run the specified shell command in each project. repo forall
The following additional environment variables are available via :
REPO_PROJECT
: The name of the item.REPO_PATH
: The relative path of the project in this workspace.REPO_REMOTE
: The name of the project's remote repository.REPO_LREV
: The revision attribute in the manifest file has been converted to a local tracking branch. Use this variable if you need to pass the revision value in the manifest to a locally running Git command.REPO_RREV
: The revision attribute in the manifest file is exactly the same as the name displayed in the manifest file.
Common options:
-c
: The command and parameters to run, that is, the shell command. This command is evaluated through /bin/sh, and any arguments after it are passed as shell positional arguments.-p
: Display the project header before the specified command output results. This is accomplished by binding pipes to the command's stdin, stdout, and sterr streams, and then piping all output into a continuous stream that is displayed in a paging session.-v
: Displays messages written to stderr by this command.
Note: When there are the above environment variables in the shell command, you need to enclose the shell command in single quotes.
Example:
- print item list
repo forall -c 'echo $REPO_PROJECT'
- print project path
repo forall -c 'echo $REPO_PATH'
repo prune
Command format:
repo download {
[project] change[/patchset]}...
Delete the merged branch. In fact, it is git branch -d
the encapsulation of the command, which is used to scan the various branches of the project and delete the branches that have been merged.
repo abandon
Command format:
repo abandon [--all | <branchname>] [<project>...]
Delete the specified branch. In fact, it is git brance -D
the encapsulation of the command.
repo upload
Command format:
repo upload [--re --cc] [<project>]...
For the specified project, Repo will compare the local branch with the remote branch that was updated at the time of the last repo sync. Repo will prompt you to select one or more branches that have not been uploaded for review.
Note: use
repo upload
needs to build a gerrit environment, andremote
addreview
attributes to the manifest file element
After you select one or more branches, all commits on the selected branches are transferred to Gerrit over an HTTPS connection. You need to configure an HTTPS password to enable upload authorization. To generate new username/password pairs for use with HTTPS transfers, visit Password Generator .
When Gerrit receives object data through its servers, it turns each commit into a change so that reviewers can comment on each commit individually. To combine several "checkpoint" commits into one, use git rebase -i
, and then run repo upload
.
If you run it without any arguments repo upload
, the action searches all projects for changes to upload.
To modify changes after they have been uploaded, you git rebase -i
should git commit --amend
update your local commit using a tool such as or . After the modification is complete, do the following:
- Check to make sure the updated branch is the currently checked out branch.
- For each commit in the corresponding series, enter the Gerrit change ID in square brackets:
# Replacing from branch foo [ 3021 ] 35f2596c Refactor part of GetUploadableBranches to lookup one specific... [ 2829 ] ec18b4ba Update proto client to support patch set replacments # Insert change numbers in the brackets to add a new patch set. # To create a new change record, leave the brackets empty.
These changes will have an additional patchset after the upload is complete.
repo upload
Equivalent git push
, but very different. It pushes the repository changes to a special reference on the code review server (Gerrit software setup). The code review server will perform special processing on the pushed submission, display the new submission as a modification set to be reviewed, and enter the code review process. Only after the review is passed, it will be merged into the official version library.
Common options:
-t
: Send the local branch name to the Gerrit code review server--re=REVIEWERS
: Ask designated personnel to review--cc=CC
: Simultaneously send notifications to the following email addresses
repo download
Command format:
repo download {
[project] change[/patchset]}...
Download specified changes from the review system and place them in your project's local working directory for use.
For example, to download change 23823 to your platforms/build directory, run the following command:
$ repo download platform/build 23823
repo sync
It should be possible to efficiently remove any commits repo download
retrieved . Alternatively, you can check out the remote branch, eg git checkout m/master
.
repo download
The command is primarily used by code reviewers to download and evaluate revisions submitted by contributors.
The contributor's revision is named in the Git repositoryrefs/changes//引用方式
(the default patchset is 1), and like other Git references, usegit fetch
Get, the latest commit pointed to by the reference is the contributor's pending revision.
Usingrepo download
the command is actually togit fetch
obtainrefs/changes//patchset>
the reference of the corresponding project, and automatically switch to the corresponding reference.
repo grep
Command format:
repo grep {
pattern | -e pattern} [<project>...]
Print out lines matching a pattern. Equivalent to a wrapper git grep
around for content lookup in project files.
repo manifest
Command format:
repo manifest [-o {
-|NAME.xml}] [-m MANIFEST.xml] [-r]
The manifest inspection tool is used to display the content of the currently used manifest file.
Common options:
-r, --revision-as-HEAD
: Save a version as the current HEAD-o -|NAME.xml, --output-file=-|NAME.xml
: Save the manifest as NAME.xml
Example:
# 获取仓库的sha1值,并记录在一个新的release.xml文件中
repo manifest -o release.xml -r
repo workflow
The common repo workflow is as follows:
After repo sync, git branch -a shows the meaning of "no branch" and "remotes/m/master"
After using the repo tool to synchronize the code, enter any project path and execute git branch -a
the output as follows:
$ git branch -a
* (no branch)
remotes/m/master -> origin/dev
remotes/origin/dev
remotes/origin/master
-
The last two lines in the output are easier to understand, they are the branches that exist in the remote warehouse of the warehouse.
-
The
* (no branch)
in*
indicates the current branch, which means that it is not currently on any branch.Why is it displayed
no branch
?
repo sync
It is only updated according torevision
the version . There is no fixed branch.repo sync
After success, it cannot be operated directly. It needs to be executed first torepo start
create a new branch for development.In fact, executing
repo branches
the command will alsono branches
display , which makes it easier to understand. Different sub-warehousesrevision
have different , and all git repositories are put together, and there is no exact branch. -
remotes/m/master -> origin/dev
What does it mean in the second line of output ?- The former part represents the branch of the repo manifest library (manifest warehouse), that is
repo init
,-b
the parameter of the option when executing the command.repo init
If-b
the option is not specified when executing the command, it means that the branch of the manifest library is used by defaultmaster
. - The latter part pointed by the arrow indicates the revision value
origin/dev
of a single git libraryproject
specified . attribute ).revision
project
revision
default
revision
The purpose of this is to let users know which branch of the list library they are currently working on conveniently. Which branch/tag of the current git library is referenced by this branch of the current manifest library
- The former part represents the branch of the repo manifest library (manifest warehouse), that is
Reference article:
- Introduction to repo tools
- An easy-to-understand repo tutorial
- Google Git-Repo multi warehouse project management
- Git multi-project management
- Multi warehouse management tool - Repo
- How to build Repo to manage multiple git warehouses for your own project?
- Repo command reference
- Repo
- After repo sync is synchronized, git branch shows "no branches"
- The meaning of the refs/remotes/m branch