AOSP: Source Code, Repo, Git

Budhdi Sharma
Android Champ
Published in
23 min readFeb 9, 2023

--

overview

Repo is a Python script developed by Android to facilitate the management of multiple git repositories. The emergence of repo is not to replace git, but to allow Android developers to use git more effectively.

The Android source code contains hundreds of git libraries, and just downloading so many git libraries is a heavy task, so when downloading the source code, Android introduces the repo. The official Android recommended way to download repo is through the Linux curl command. After downloading, add executable permissions to the repo script:

$ curl https : // storage . googleapis .com / git - repo - downloads / repo > ~ / bin / repo
$chmod a+x ~ /bin/ repo

Note: The above repo command may change so use another third party channel to get the correct repo libraries.

How Repo works

Repo needs to pay attention to the number, name, path, etc. of the current git library. With these basic information, these git libraries can be operated. By centrally maintaining the list of all git libraries, repo can easily obtain the information of git libraries from the list. This list will change as the version evolves and upgrades, and there are also some local modification and customization requirements. Therefore, repo manages the project’s manifest file through a git library. The name of this git library is manifests.

After opening the executable python script repo, I found that the amount of code is not large (no more than 1000 lines). Could it be that this script alone has managed the management of hundreds of git libraries in AOSP? it’s not true. Repo is a collection of scripts, which are also maintained through the git library. The name of the git library is repo.

When the client uses repo to initialize a project, the two git libraries, manifests and repo, will be copied from the remote to the local, but this is almost invisible to Android developers (generally through the file manager, it is impossible to See those two git repositories). Repo hides the automated management information in the .repo subdirectory of the root directory.

Manifests Repository (.repo/manifests)

Under the git library of the AOSP project list, there is only one file default.xml, which is a standard XML that describes all the information managed by the current repo. The content of the default.xml file of AOSP is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote name="aosp"
fetch=".."
review="https://android-review.googlesource.com/" />
<default revision="master"
remote="aosp"
sync-j="4" />
<project path="build" name="platform/build" groups="pdk,tradefed" >
<copyfile src="core/root.mk" dest="Makefile" />
</project>
<project path="abi/cpp" name="platform/abi/cpp" groups="pdk" />
<project path="art" name="platform/art" groups="pdk" />
...
<project path="tools/studio/translation" name="platform/tools/studio/translation" groups="notdefault,tools" />
<project path="tools/swt" name="platform/tools/swt" groups="notdefault,tools" />
</manifest>

<remote>: Describes the basic information of the remote warehouse. name describes the name of a remote warehouse, usually the name we see is origin; fetch is used as the leading edge of the project name, and is used when constructing the remote address of the project warehouse; review describes the server address used for code review

<default>: The defined attributes of the default tag will be used as the default attributes of the <project> tag, and these attributes can also be rewritten in the <project> tag. The attribute revision indicates the current version, which is what we commonly call a branch; the attribute remote describes the remote warehouse name used by default, that is, the attribute value of name in the <remote> tag; the attribute sync-j indicates that when synchronizing remote code, concurrent The number of tasks, the machine with high configuration can increase this value

<project>: Each git library managed by repo corresponds to a <project> tag, path describes the path of the project relative to the remote warehouse URL, and will be used as the path of the corresponding git library in the local code; name is used for Define the project name, and the naming method adopts the relative address of the entire project URL.

If you need to add or replace some git libraries, you can do it by modifying default.xml, and repo will be automatically managed according to the configuration information. However, the direct customization of default.xml may cause conflicts with the remote default.xml when the project list is updated next time. Therefore, repo provides a more flexible customization method local_manifests: all customizations follow the default.xml specification, and the file name can be customized, such as local_manifest.xml, another_local_manifest.xml, etc., and put the customized XML in the newly created The .repo/local_manifests subdirectory is fine. repo will traverse all *.xml files in the .repo/local_manifests directory, and finally merge with default.xml into a total project manifest file manifest.xml.

An example modification of local_manifests is as follows:

$ ls .repo/local_manifests
local_manifest.xml
another_local_manifest.xml
$ cat .repo/local_manifests/local_manifest.xml
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<project path="manifest" name="tools/manifest" />
<project path="platform-manifest" name="platform/manifest" />
</manifest>

repo script repository (.repo/repo)

Repo encapsulates git commands and provides a set of repo commands (including init, sync, etc.), and all automatic implementations of repo management are also included in this git library. When initializing for the first time, repo will download this git repository from remote to local.

Repository directory and working directory

The warehouse directory saves historical information and modification records, and the working directory saves the information of the current version. Generally speaking, a project’s Git warehouse directory (the default is the .git directory) is located under the working directory, but Git supports storing a project’s Git warehouse directory and working directory separately. For repo management, there are both separate storage and storage in the working directory:

manifests: There are two copies of the warehouse directory, one is located in the .git directory of the working directory (.repo/manifests), and the other is stored independently in .repo/manifests.git

repo: The warehouse directory is located in the .git directory of the working directory (.repo/repo)

project: All warehouse directories of managed git libraries are stored separately, located in the .repo/projects directory. At the same time, the .git of the working directory is also preserved, but all the files in it are links to the .repo. In this way, separate storage is achieved, and all git commands in the working directory are also compatible.

Since all the information of the project is saved in the .repo directory, when you want to copy a project, you only need to copy this directory. Repo supports restoring the original project from the existing .repo locally.

Introduction

The usage format of the repo command is as follows:

$ repo <COMMAND> <OPTIONS>

The options are: help, init, sync, upload, diff, download, forall, prune, start, status, and each command has an actual usage scenario. Let’s give a brief introduction to these commands first:

3.1 init
$ repo init -u <URL> [<OPTIONS>]
-u: Specify the URL of the remote git library of manifests, which is a list of the entire project. By default, this git library only contains a default.xml file, its content can be found in the Android sample
-m, --manifest- name : Specifies the manifest file in the manifests library that is required. By default, manifests/default.xml will be used-b, --manifest-branch: Specify a version in the manifest.xml file, which is commonly known as "branch"After running this command, a new .repo subdirectory will be created in the current directory:.repo
├── manifests # A git library, including the default .xml file, used to describe the information of the git library managed by repo
├── manifests.git # manifest is the entity of the git library, and all files in the manifest/.git directory will be linked to this directory
├── manifest.xml # A soft link of manifests/ default .xml
└── repo # A git library, including all scripts run by repo

How are these local directories generated? When executing the repo command, you can pass the — trace parameter to see what actually happened.

$ repo --trace init -u $URL -b $BRANCH -m $MANIFEST
--------------------
mkdir .repo; cd .repo
git clone --bare $URL manifests.git
git clone https://android.googlesource.com/tools/repo
mkdir -p manifests/.git; cd manifests/.git
for i in ../../manifests.git/*; do ln -s $ı .; done
cd ..
git checkout $BRANCH -- .
cd ..
ln -s manifests/$MANIFEST manifest.xml

First, create a .repo subdirectory in the current directory, and all subsequent operations are completed in the .repo subdirectory;

Then, clone two git libraries, one of which is the manifests specified by the -u parameter, the name of the local git library is manifest.git; the other is the default repo, and we will see later that this URL can also be specified by parameters;

Next, the manifest/.git directory is created, and all the files in it are links to the manifests.git directory. This is to facilitate the execution of the git command on the manifests directory. Then, the manifest will be switched to the one specified by the -b parameter. branch;

Finally, in the .repo directory, a soft link is created to link to the manifest file specified by the -m parameter. The default is manifests/default.xml.

In this way, the initialization of a multi-git library is completed, and then other repo commands can be executed.

We also introduce several parameters that are not commonly used

–repo-url: Specify the URL of the remote repo library, but domestic access to Google is restricted, which will cause the library to fail to download, which will cause repo init to fail, so you can pass This parameter specifies a repo address with unlimited access

–repo-branch: Like the git library of manifest, the git library of repo also has version differences. This parameter can be used to specify the specific branch to download the remote git library of repo

–no-repo-verify: When downloading the repo library, the source code of the repo will be checked. When the third-party repo library is specified through –repo-url, the inspection may fail, so this parameter can be used together to force no inspection

sync

$ repo sync [PROJECT_LIST]
Download the remote code and update the local code to the latest, this process is called “synchronization”. If no parameters are used, all repo management will be synchronized; the PROJECT_LIST parameter can also be used to specify several PROJECTs to be synchronized. Depending on the local git library code, the synchronization operation will have different behaviors:

When the local git library triggers the synchronization operation for the first time, then this command is equivalent to git clone, which will directly copy the remote git library to the local

When the synchronization operation has been triggered locally, then this command is equivalent to git remote update && git rebase origin/<BRANCH>, <BRANCH> is the code merge of the remote branch currently associated with the local branch may cause conflicts, when the conflict When it appears, you only need to resolve the conflict, and then execute git rebase — continue.

When the sync command is executed correctly, the local code is consistent with the remote code. In some scenarios, we will use some parameters of the sync command:

-j: Enable multi-threaded synchronization operation, which will speed up the execution of the sync command. By default, 4 threads are used for sync concurrently

-c, — current-branch: Only sync the specified remote branch. By default, sync will synchronize all remote branches. When there are many remote branches, the amount of downloaded code will be large. Using this parameter can reduce download time and save local disk space

-d, — detach: Detach from the current local branch and switch to the branch set in manifest.xml. In actual operation, this parameter is very useful. When we sync the code for the first time, we often switch to the dev branch for development. If you use sync without this parameter, it will trigger the local dev branch to merge with the remote branch set by the manifest, which will likely cause sync to fail

-f, — force-broken: When a git library sync fails, the entire synchronization operation will not be interrupted, and other git libraries will continue to be synchronized

–no-clone-bundle: When initiating a request to the server, in order to achieve the fastest response speed, a content delivery network (CDN, Content Delivery Network) will be used. The synchronization operation will also establish a connection with the nearest server through the CDN, and use $URL/clone.bundle of HTTP/HTTPS to initialize the local git library. The clone.bundle is actually a mirror image of the remote git library, which is downloaded directly through HTTP, which will Make better use of network bandwidth and speed up downloads. When the server cannot respond to download $URL/clone.bundle normally, but git can work normally, you can use this parameter to configure not to download $URL/clone.bundle, but to download the remote git library directly through git

upload

$ repo upload [PROJECT_LIST]
Literally, upload is to upload, upload the local code to the remote server. The upload command will first find out the changes that have occurred in the local branch since the last synchronization operation, and then generate a Patch file for these changes and upload them to the Gerrit server. If PROJECT_LIST is not specified, upload will find out the changes of all git libraries; if a git library has multiple branches, upload will provide an interactive interface, prompting to select several branches for uploading.

upload will not directly merge the changes into the remote git repository, but needs to be approved by Reviewer first. Reviewer checks the changed content and decides whether to approve the merged code, all through Gerrit. The address of the Gerrit server is specified in the manifests: open .repo/manifest.xml, and the value of the review attribute in the XML TAG <remote> is the URL of the Review server:

<remote name=”aosp”
fetch=”..”
review=”https://android-review.googlesource.com/" />
The implementation mechanism of Gerrit is not discussed in this article, but there are several concepts related to Gerrit , which needs to be understood by the code submitter:

Reviewer: There can be multiple code reviewers, which need to be designated manually. Gerrit provides the operation of the webpage, you can fill in Reviewer. When there are multiple git library changes submitted, in order to avoid the repetitive work of frequently filling in the Reviewer on the web page, upload provides the –re, –reviewer parameters to specify the Reviewer at one time on the command line

Commit-ID: In order to identify each commit, git introduces Commit-ID, which is a SHA-1 value. A Checksum for the current commit content can be used to verify the integrity of the commit content

Change-ID: Gerrit introduces a Change-ID for each Review task. Every submission uploaded to Gerrit will correspond to a Change-ID. In order to distinguish it from the Commit-ID, Gerrit sets the Change-ID to be in uppercase Beginning with the letter “I”. Change-ID and Commit-ID are not one-to-one correspondence, each Commit-ID will be associated with a Change-ID, but Change-ID can be associated with multiple Commit-ID

Patch-Set: Changes that currently require Review. A Change-ID is associated with multiple Commit-IDs, which is represented by Patch-Set. When the last commit is corrected and uploaded through the git commit — amend command, the Commit-ID has changed, but the Change can still be maintained -ID remains unchanged, so that under Gerrit’s original Review task, a new Patch-Set will appear. How many Patch-Sets will appear as many revisions are made. It is understandable that only the last revision is the result we want. Therefore, among all Patch-Sets, only the latest one is really useful and can be merged. .

download

$ repo download <TARGET> <CHANGE>
upload is to submit changes to Gerrit, and download is to download changes from Gerrit. Like upload, the download command is also used with Gerrit.

<TARGET>: Specify the PROJECT to download, such as platform/frameworks/base, platform/packages/apps/Mms

<CHANGE>: Specifies the changes to download. This value is neither Commit-ID nor Change-ID, but the last few digits of a Review task URL.

forall

$ repo forall [PROJECT_LIST] -c <COMMAND>
Execute the command sequence specified by the -c parameter for the specified git repository. This is a very useful command when managing multiple git repositories. PROJECT_LIST is separated by spaces, for example:

$ repo forall frameworks/base packages/apps/Mms -c “git status”
means to execute the git status command on platform/frameworks/base and platform/packages/apps/Mms at the same time. If PROJECT_LIST is not specified, then the command will be executed simultaneously for all git libraries managed by the repo.

There are some other parameters of this command:

-r, –regex: By specifying a regular expression, only the matching PROJECT will execute the specified command

-p: In the output result, print the name of PROJECT

prune

$ repo prune [<PROJECT_LIST>]
Delete the merged branches in the specified PROJECT. After the code on the development branch has been merged into the main branch, use this command to delete the development branch.

With the evolution of time, there will be more and more development branches. When multiple people develop the same git library, the situation of multiple development branches will become more and more obvious. Suppose the current git library has the following branches:

* master 
dev_feature1_201501 # has been merged into master
dev_feature2_201502 # has been merged into master
dev_feature3_201503 # is under development, and there are still changes that have not been merged into master

Then, using the prune command against the git library will delete dev_feature1_201501 and dev_feature2_201502.

Define and delete useless branches, which can contribute to the development and management efficiency of the team. Prune is the “killer tool” for deleting useless branches.

start

$ repo start <BRANCH_NAME> [<PROJECT_LIST>]
On the specified PROJECT, switch to the branch specified by <BRANCH_NAME>. You can use the — all parameter to perform branch switching operations on all PROJECTs. This command is actually an encapsulation of the git checkout command, <BRANCH_NAME> is customized, and it will track the branch name specified in the manifest.

After the code is synced for the first time, the git library can be switched to the development branch through the start command, so as to avoid the situation of losing the changed content caused by working on the anonymous branch.

status

$ repo status [<PROJECT_LIST>]
status is used to view the status of multiple git libraries. In fact, it is an encapsulation of the git status command.

Practice

The recommended development process for Android is:

Repo init initializes the project, specifying the branch to be downloaded
repo sync download code
repo start switch the local git library to the development branch (TOPIC BRANCH)

Modify locally, after verification, submit to the local
repo upload upload to the server, and wait for review
In the actual use process, what subcommands and parameters of the repo will we use? What parameters help to improve development efficiency? Let’s take some actual scenarios as examples to explain.

Customize the project manifest file

Through the local_manifest mechanism, it is possible to avoid directly modifying default.xml, which will not cause conflicts in the next synchronization of remote manifest files.

CyanogenMod (CM) is compatible with hundreds of models, and the git libraries involved in different models may be different. Take the customization of the manifest file by CM as an example, by adding local_manifest.xml, the content is as follows:

<manifest>
<!-- add github/gitlab/gerrit as a remote source -->
<remote name="github" fetch="git://github.com" />

<!-- remove aosp standard projects and replace with cyanogenmod versions -->
<remove-project name="platform/bootable/recovery" />
<remove-project name="platform/external/yaffs2" />
<remove-project name="platform/external/zlib" />
<project path="bootable/recovery" name="CyanogenMod/android_bootable_recovery" remote="github" revision="cm-10.1" />
<project path="external/yaffs2" name="CyanogenMod/android_external_yaffs2" remote="github" revision="cm-10.1" />
<project path="external/zlib" name="CyanogenMod/android_external_zlib" remote="github" revision="cm-10.1" />

<!-- add busybox from the cyanogenmod repository -->
<project path="external/busybox" name="CyanogenMod/android_external_busybox" remote="github" revision="cm-10.1" />

</manifest>

local_manifest.xml will be integrated with the existing default.xml into a project manifest file manifest.xml, which realizes the replacement and addition of some git libraries. The current manifest file can be exported by the following command, and the final snapshot.xml is the merged version:

$ repo manifest -o snapshot.xml -r

Before compiling, save the manifest of the whole project, which can help to trace back the problem. When the git library of the project changes and needs to be rolled back to the previous version for verification, you only need to re-initialize the previous version based on snapshot.xml:

$ cp snapshot.xml .repo/manifests/ 
$ repo init -m snapshot.xml # -m parameter indicates a custom manifest
$ repo sync -d # -d parameter indicates breaking away from the current branch and switching to the branch defined in the manifest

Solve the problem that the Android source code cannot be downloaded

During repo init, two git libraries, manifests and repo, will be downloaded remotely. By default, the addresses of these two git libraries are hard-coded in the repo python script. For AOSP, the addresses of these two git libraries are obviously provided by google. However, due to limited access to Google, manifests and repo cannot be downloaded during init. At this time, you can use the -u and — repo-url parameters of init to customize the addresses of these two libraries, supplemented by — no-repo-verify to bypass code inspection.

$ repo init --repo-url [PATH/TO/REPO] -u [PATH/TO/MANIFEST] -b [BRANCH] --no-repo-verify
$ repo sync

Download remote code faster and cheaper

By default, repo will synchronize the code of all remote branches of the git library, but in the actual development process, the branches used are limited. Use the -c parameter of sync to download only the branches set in the manifest, which will save code download time and local disk space:

$ repo sync -c

If you need to use another branch in the actual development process and do not want to be interfered by other branches, you can use the following command in the root directory of the existing project:

$ repo manifest -o snapshot.xml -r
$ repo init -u [PATH/TO/MANIFEST] -b [ANOTHER_BRANCH]
$ repo sync -c -d

The above command sequence quite updates the manifest, and only downloads the code of ANOTHER_BRANCH, so that only the code of two branches is saved locally. Using the saved snapshot.xml, all git libraries can be easily switched back to the original branch.

If there is already an Android source code locally, assuming the path is ~/android-exsit, and you want to download another new Android source code, you can download the code within a few minutes through the –reference parameter:

$ mkdir ~/android-new && cd ~/android-new
$ repo init --reference=~/android-exsit -u [PATH/TO/MANIFEST] -b [BRANCH]
$ repo sync -c

Avoid working on anonymous branches

After the code is synced, all git libraries are on an anonymous branch (no branch) by default, and it is easy to lose code modifications due to misoperation. You can use the following command to switch all git repositories to the development branch:

$ repo start BRANCH --all

Use upload to submit code

Developers may make modifications on multiple git libraries or even multiple branches at the same time, and it is cumbersome to submit codes for each git library separately. You can use the following command to submit all the changes together:

$ repo upload

Don’t worry about missed submissions or wrong submissions, upload will provide an interactive interface, and developers can choose the git library and branch to be submitted.

If you need to omit the operation of filling in the reviewer on Gerrit, you can use the — reviewer parameter to specify the Reviewer’s email address:

$ repo upload --reviewer="budhdisharma@gmail.com"

Periodically delete merged development branches

Git encourages creating a new branch when fixing bugs or developing new features. Creating Git branches is cheap and fast, so instead of worrying about the cost of creating Git branches, use branches as much as possible.

As time goes by, there will be more and more development branches, and some development branches that have been merged into the trunk have no value. You can periodically delete useless development branches through the prune command:

$ repo prune [PROJECT_LIST]

Operate multiple git libraries at the same time

For some developers, it is normal to operate multiple git libraries at the same time. If the operation commands for each git library are the same, you can use the following command to complete all operations at once:

$ repo forall -c "git branch | grep tmp | xargs git branch -D; git branch"

The command sequence specified by the parameter -c can be very complicated, and multiple commands only need to be separated by “;”.

download source code

Google official website tutorial:

https://source.android.com/source/downloading.html

The Android source tree is in a Git repository hosted by Google. The Git repository contains metadata about the Android source code, including metadata about changes made to the source code and the dates of the changes. This document describes how to download the source tree for a specific Android codeline.

To start with a factory image for a specific device, see Choosing a Device Version.

Install Repo

Repo is a tool that makes it easier to use Git in an Android environment.

mkdir ~/bin
PATH=~/bin:$PATH

Download the Repo tool, and make sure it is executable:

curl https : // storage . googleapis .com / git - repo - downloads / repo > ~ / bin / repo
chmod a+x ~ /bin/ repo

Initialize the Repo client, creating an empty directory to hold your working files.

mkdir WORKING_DIRECTORY
cd WORKING_DIRECTORY

Configure the git repository with a valid email:

git config --global user.name "Budhdi Sharma"
git config --global user.email "budhdisharma@gmail.com"

Run repo init to get the latest version of the Repo with any recent bugfixes.

repo init https: // android.googlesource.com /platform/m anifest

To checkout against a branch other than “master”, use -b to specify the branch. For a list of branches, see Source Tags and Versions.

repo init -u https://android.googlesource.com/platform/manifest -b android_version_branch_tag

After successful initialization, a .repo folder will be generated in the current directory:

Download the Android source tree

To download the Android source tree from the repository specified in the default manifest to the working directory, run the following command:

repo sync

The Android source code files will be located in the working directory under the corresponding project name.

Troubleshoot network issues

When downloading content using a proxy (common in some enterprise environments), you may need to explicitly specify the proxy that Repo then uses:

export HTTP_PROXY=http://<proxy_user_id>:<proxy_password>@<proxy_server>:<proxy_port>
export HTTPS_PROXY=http://<proxy_user_id>:<proxy_password>@<proxy_server>:<proxy_port>
sudo sysctl -w net.ipv4.tcp_window_scaling=0
repo sync -j1

Use a local mirror

When you’re using multiple clients (especially if you’re running low on bandwidth), it’s best to create a local mirror of all server content and sync clients from that mirror (no network access required). The download file for a full image is smaller and contains more information than the download file for two clients.

The following instructions assume that the mirror is created in /usr/local/aosp/mirror. The first step is to create and synchronize the mirror itself. Note the — mirror flag, which can only be specified when creating a new client:

mkdir -p /usr/local/aosp/mirror
cd /usr/local/aosp/mirror
repo init -u https://android.googlesource.com/mirror/manifest --mirror
repo sync

Once the mirror is synchronized, you can create new clients from the mirror. Note that it is important to specify an absolute path:

mkdir -p /usr/local/aosp/master
cd /usr/local/aosp/master
repo init -u /usr/ local /aosp/mi rror /platform/m anifest.git
repo sync

Finally, to sync the client with the server, you need to sync the mirror with the server, and then sync the client with the mirror:

cd /usr/local/aosp/mirror
repo sync
cd /usr/local/aosp/master
repo sync

You can store the image on a LAN server and access it via NFS, SSH or Git. You can also store it on a removable memory drive and transfer it between users or computers.

to develop

To work with Android code, you need to use both Git and Repo. In most cases, you can use just Git (not Repo), or combine Repo and Git commands to form complex commands. However, using Repo to perform basic cross-network operations can greatly simplify your work.

Development tools: git, Repo, Gerrit, Android Studio

Git is an open source version control system designed for handling large projects spread across multiple code repositories. In the Android environment, we will use Git to perform local operations such as creating local branches, submitting, viewing changes, and modifying. One of the challenges in building an Android project is determining how best to support external communities — from the hobbyist community to the large original equipment manufacturers (OEMs) producing mass consumer devices. We want components to be replaceable, and interesting components to evolve on their own outside of Android. We initially decided on a distributed revision control system, screened it, and settled on Git.

Repo is our repository management tool built on top of Git. Repo can consolidate multiple Git repositories when necessary, upload related content to our revision control system, and automate parts of the Android development workflow. Repo is not meant to replace Git, just to make it easier for you to use Git in an Android environment. A repo command is an executable Python script that you can place anywhere on your path. When working with Android source code files, you can use Repo to perform operations across the network. For example, you can download files from multiple repositories to your local working directory with a single Repo command.

Gerrit is a web-based code review system for projects using Git. Gerrit encourages more focused use of Git by allowing all authorized users to submit changes that are automatically incorporated into the project if they pass code review. Additionally, Gerrit can display changes side-by-side in the browser and supports in-code comments, making auditing easier.

Android Studio is the official Integrated Development Environment (IDE) for developing Android applications. For more information, see Android Studio overview.

Basic Workflow Schematic Diagram of Basic Workflow
Figure 1. Android Basic Workflow

The basic pattern for interacting with the codebase is as follows:

Use repo start to create a new topic branch.

Modify the file.

Use git add to stage changes.
Commit your changes
with git commit .
Use repo upload to upload changes to the review server.

task reference

The following task list briefly summaries how to perform common Repo and Git tasks. To learn how to use Repo to download source code, see Downloading Source Code and Using Repo.

sync client

To sync files for all available projects, run the following command:

repo sync

To sync the files of the selected project, run the following command:

repo sync PROJECT0 PROJECT1 ... PROJECTN

Create topic branch

When you start making changes (such as when you start working on a bug or using a new feature), create a new topic branch in your local working environment. A topic branch is not a copy of the original; it represents a specific commit. This way, you can easily create local branches and switch between them. By using branches, you can separate certain aspects of your work from other aspects.

To create a new topic branch using the Repo, go to the project you want to modify and run the following command:

repo start BRANCH_NAME .

Note that periods represent items in the current working directory. To verify that your new branch was created, run the following command:

repo status .

Using topic branches
To assign a branch to a specific project, run the following command:

repo start BRANCH_NAME PROJECT_NAME

To see a list of all projects, visit android.googlesource.com. Again, if you’re already in a specific project directory, you can simply use a period to indicate the current project.

To switch to another branch that you have already created in your local work environment, run the following command:

git checkout BRANCH_NAME

To see a list of existing branches, run the following command:

git branch

or

repo branches

The name of the current branch will be preceded by an asterisk.

Note: If there is a bug, it may cause repo sync to reset the local topic branch. If git branch says * (no branch) after you run repo sync, run git checkout again.

Staging Files
By default, Git detects the changes you make in your project, but doesn’t track them. For Git to save your changes, you must mark the changes to be included in a commit. This is also known as “staging”.

You can stage your changes by running:

git add

For this command, any file or directory within the project directory can be used as an argument. git add does not simply add files to the Git code base as its name suggests, it can also be used to temporarily store modified and deleted content of files.

View Client Status
To list the status of the files, run the following command:

repo status

To view uncommitted changes, run the following command:

repo diff

If you’re ready to commit right away, running the repo diff command will show you every local change you’ve made that wouldn’t have been committed. If you are going to commit right away, to see every change that will be committed, you need to run the Git command git diff. Before running this command, make sure you are in the project directory:

cd ~/WORKING_DIRECTORY/PROJECT
git diff --cached

Committing Changes
In Git, a commit is the basic unit of revision control, containing a snapshot of the directory structure as well as the file contents of the entire project. Creating a commit in Git is as simple as typing the following command:

git commit

You’ll be prompted to provide a commit message using your favorite editor; please provide a helpful message for any changes you commit to AOSP. If you don’t add a log message, the commit will abort.

Update to the latest revision before uploading changes to Gerrit :

repo sync

Then run the following command:

repo upload

After running this command, your committed changes will be listed and you will be prompted to select a branch to upload to the review server. If there is only one branch, you will see a simple y/n prompt.

Reverting sync conflicts
If repo sync shows sync conflicts, do the following:

View unmerged files (status code = U).
Modify where conflicts exist as needed.
Make changes in the relevant project directory, run git add and git commit for the relevant files, then “rebase” those changes. For example:

git add .
git commit
git rebase --continue

When the rebase is complete, start the whole synchronisation process again:

repo sync PROJECT0 PROJECT1 ... PROJECTN

Clean up your client files
To update your local working directory after the changes have been merged into Gerrit, run the following command:

repo sync

To safely remove an outdated topic branch, run the following command:

repo prune

Removing a client
Since all state information is stored on the client, you can simply remove the directory from the file system:

rm -rf WORKING_DIRECTORY

Deleting the client will permanently delete any changes you have not uploaded for review.

Git and Repo Quick Reference Sheet List of Basic Git and Repo Commands
Figure 2. Basic Git and Repo Commands

--

--

Budhdi Sharma
Android Champ

As an AOSP developer, I specialize in creating robust framework and system applications that seamlessly integrate with embedded systems on various SOCs