repo
overview
Git
Git is an open-source version-control system designed to handle very large projects that are distributed over multiple repositories.
In the context of Android, we use Git for local operations such as local branching, commits, diffs, and edits.
One of the challenges in setting up the Android project was figuring out how to best support the outside community--from the hobbiest community to large OEMs building mass-market consumer devices. We wanted components to be replaceable, and we wanted interesting components to be able to grow a life of their own outside of Android. We first chose a distributed revision control system, then further narrowed it down to Git.
Repo
Repo is a repository management tool that we built on top of Git.
Repo unifies the many Git repositories when necessary,
does the uploads to our revision control system
automates parts of the Android development workflow.
Repo is not meant to replace Git, only to make it easier to work with Git in the context of Android. The repo command is an executable Python script that you can put anywhere in your path.
In working with the Android source files, you will use Repo for across-network operations. For example, with a single Repo command you can download files from multiple repositories into your local working directory.
AOSP是由许许多项目组成的,例如,在Android 4.2中,就包含了329个项目,每一个项目都是一个独立的Git仓库。这意味着,如果我们要创建一个AOSP分支来做feature开发,那么就需要到每一个子项目去创建对应的分支。这显然不能手动地到每一个子项目里面去创建分支,必须要采用一种自动化的方式来处理。这些自动化处理工作就是由Repo工具来完成的。当然,Repo工具所负责的自动化工作不只是创建分支那么简单,查看分支状态、提交代码、更新代码等基础Git操作它都可以完成。
Repo命令想操作的是AOSP。这就要求Repo命令要知道AOSP都包含有哪些子项目,并且要知道这些子项目的名称、仓库地址是什么。换句话说,就是Repo命令要知道AOSP所有子项目的Git仓库元信息。我们知道,AOSP也是不断地迭代法变化的,例如,它的每一个版本所包含的子项目可能都是不一样的。这意味着需要通过另外一个Git仓库来管理AOSP所有的子项目的Git仓库元信息。这个Git仓库在AOSP里面就称为Manifest仓库。
- Repo仓库:Repo工具的那些Python脚本本身也是一个Git仓库
- Manifest仓库:管理AOSP所有的子项目的Git仓库元信息。这个Git仓库在AOSP里面就称为Manifest仓库
- AOSP子项目仓库:Android下的子项目Git仓库
Gerrit
Gerrit is a web-based code review system for projects that use git.
Gerrit encourages more centralized use of Git by allowing all authorized users to submit changes, which are automatically merged if they pass code review.
In addition, Gerrit makes reviewing easier by displaying changes side by side in-browser and enabling inline comments.
Basic Workflow
The basic pattern of interacting with the repositories is as follows:
- Use repo start to start a new topic branch.
- Edit the files.
- Use git add to stage changes.
- Use git commit to commit changes.
- Use repo upload to upload changes to the review server.
Installing Repo
Make sure you have a bin/ directory in your home directory, and that it is included in your path:
$ mkdir ~/bin $ PATH=~/bin:$PATH
Download the Repo script and ensure it is executable:
$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo $ chmod a+x ~/bin/repo
Task reference
help
repo help
provides command-line help for repo sub-commands. For example to display help on the repo upload command
$ repo help upload
git config
When the git commit author is not set and Gerrit rejects it
Fix your ID by doing the following:
$ git config --global user.email user@xxxx.com $ git config --global user.name 'First Last user@xxxx.com'
Then the commit must be ammended:
$ git commit --amend --author 'First Last user@xxxx.com'
This will get the correct author on the commit.
Synchronizing your client
To synchronize the files for all available projects:
$ repo sync
Syncing with multiple threads
Newer versions of tools/repo.git support multiple threads
We suggest no more than 4 as then you will notice slowness from your local machine disk I/O, and extra burden on the remote git server.
$ repo sync --jobs=4 or repo sync -j4
To synchronize the files for selected projects:
$ repo sync PROJECT0 PROJECT1 PROJECT2 ...
Creating topic branches
Start a topic branch in your local work environment whenever you begin a change, for example when you begin work on a bug or new feature.
A topic branch is not a copy of the original files; it is a pointer to a particular commit. This makes creating local branches and switching among them a light-weight operation. By using branches, you can isolate one aspect of your work from the others.
To start a topic branch using Repo:
$ repo start BRANCH_NAME
To verify that your new branch was created:
$ repo status
Using topic branches
To assign the branch to a particular project:
$ repo start BRANCH_NAME PROJECT
To switch to another branch that you have created in your local work environment:
$ git checkout BRANCH_NAME
To see a list of existing branches:
$ git branch
or
$ repo branches
The name of the current branch will be preceded by an asterisk.
- Note: A bug might be causing repo sync to reset the local topic branch. If git branch shows * (no branch) after you run repo sync, then run git checkout again.
Staging files
By default, Git notices but does not track the changes you make in a project. In order to tell git to preserve your changes, you must mark them for inclusion in a commit. This is also called "staging".
You can stage your changes by running
git add
which accepts as arguments any files or directories within the project directory. Despite the name, git add does not simply add files to the git repository; it can also be used to stage file modifications and deletions.
Viewing client status
To list the state of your files:
$ repo status
To see uncommitted edits:
$ repo diff
The repo diff command shows every local edit that you have made that would not go into the commit, if you were to commit right now.
To see every edit that would go into the commit if you were to commit right now, you need a Git command, git diff. Before running it, be sure you are in the project directory
$ cd ~/WORKING_DIRECTORY/PROJECT
$ git diff --cached
Committing changes
A commit is the basic unit of revision control in git, consisting of a snapshot of directory structure and file contents for the entire project.
Creating a commit in git is as simple as typing
git commit
You will be prompted for a commit message in your favorite editor; please provide a helpful message for any changes you submit to the AOSP. If you do not add a log message, the commit will be aborted.
Uploading changes to Gerrit
Before uploading, update to the latest revisions:
repo sync
Next run
repo upload
This will list the changes you have committed and prompt you to select which branches to upload to the review server. If there is only one branch, you will see a simple y/n prompt.
Adding a mandatory Reviewer
$ repo upload --reviewers=xxxx@xxxx.com
Recovering sync conflicts
If a repo sync shows sync conflicts:
- View the files that are unmerged (status code = U).
- Edit the conflict regions as necessary.
- Change into the relevant project directory, run git add and git commit for the files in question, and then "rebase" the changes. For example:
$ git add . $ git commit $ git rebase --continue
When the rebase is complete start the entire sync again:
$ repo sync PROJECT0 PROJECT1 ... PROJECTN
Cleaning up your client files
To update your local working directory after changes are merged in Gerrit:
$ repo sync
To safely remove stale topic branches:
$ repo prune
Deleting a client
Because all state information is stored in your client, you only need to delete the directory from your filesystem:
$ rm -rf WORKING_DIRECTORY
Deleting a client will permanently delete any changes you have not yet uploaded for review.
example
Android example
Initializing a Repo client
After installing Repo, set up your client to access the android source repository:
Create an empty directory to hold your working files. If you're using MacOS, this has to be on a case-sensitive filesystem. Give it any name you like:
$ mkdir WORKING_DIRECTORY $ cd WORKING_DIRECTORY
Run repo init to bring down the latest version of Repo with all its most recent bug fixes. You must specify a URL for the manifest, which specifies where the various repositories included in the Android source will be placed within your working directory.
$ repo init -u https://android.googlesource.com/platform/manifest
To check out a branch other than "master", specify it with -b:
$ repo init -u https://android.googlesource.com/platform/manifest -b android-4.0.1_r1
When prompted, please configure Repo with your real name and email address.
A successful initialization will end with a message stating that Repo is initialized in your working directory. Your client directory should now contain a .repo directory where files such as the manifest will be kept.
To pull down files to your working directory from the repositories as specified in the default manifest, run
$ repo sync
The Android source files will be located in your working directory under their project names.
special cases
Linux AU tags
The below procedure requires a completely new sync'd tree but is necessary in some circumstances. However, much quicker and easier is, especially if only going back a few days (wouldn't recommend it to go back too far):
$ repo forall -c 'git checkout au-01.08.01.xxx'
Each Android AU Release creates a versioned manifest and tags for all projects.
- The versioned manifest (versioned.xml) lists the specific commit IDs for all projects at AU creation time.
- The versioned manifest and tags point to the same commit IDs.
- The versioned manifest is itself tagged using the AU name, allowing Repo to pull the Android source at a specific AU tag.
Sync an Android source tree at a specific AU using both the tag name and versioned manifest.
$ repo init -u git://git.quicinc.com/platform/manifest.git -b refs/tags/AU_LINUX_ANDROID_GINGERBREAD.02.03.01.00.037 -m versioned.xml
$ repo sync
Syncing AUs
The AU tag is given to repo to pull a source branch at the release point
$ repo init -u git://git.quicinc.com/platform/manifest.git -b refs/tags/au-01.08.00.006 $ repo sync
Download a patch
repo downlod
The 'repo download' command downloads a change from the review system and makes it available in your project's local working directory.
repo download kernel/msm 30366/1
checkout
Fetches named heads or tags from one or more other repositories, along with the objects necessary to complete them.
git fetch ssh://xxx.com:29418/kernel/xxx refs/changes/66/30366/1 && git checkout FETCH_HEAD
pull
git pull ssh://xxx.com:29418/kernel/xxx refs/changes/66/30366/1
cherry-pick
Apply the changes introduced by some existing commits
git fetch ssh://xxx.com:29418/kernel/xxx refs/changes/66/30366/1 && git cherry-pick FETCH_HEAD
patch
git fetch ssh://xxx.com:29418/kernel/xxx refs/changes/66/30366/1 && git format-patch -1 --stdout FETCH_HEAD
Reference
repo help [command]
usage: repo COMMAND [ARGS]
The most commonly used repo commands are:
abandon Permanently abandon a development branch
branch View current topic branches
branches View current topic branches
checkout Checkout a branch for development
cherry-pick Cherry-pick a change.
diff Show changes between commit and working tree
download Download and checkout a change
grep Print lines matching a pattern
init Initialize repo in the current directory
list List projects and their associated directories
prune Prune (delete) already merged topics
rebase Rebase local branches on upstream branch
smartsync Update working tree to the latest known good revision
stage Stage file(s) for commit
start Start a new branch for development
status Show the working tree status
sync Update working tree to the latest revision
upload Upload changes for code review
See 'repo help
See 'repo help --all' for a complete list of recognized commands.