When we talk about Android project, we get a picture of repository with lots of folder inside that. Android project is large, keeping all android OS file into one repository is inefficient and error prone. If repository got corrupted whole project will be in soup as well as all git operation will be very slow in one single repository. So android project has been divided into multiple git repositories. In git any repository is maintained by .git folder.
So android source is having multiple .git folders like below picture
Here bionic.git is one repository containing file related to bionic.
kernel.git it containing kernel related files.
Other folder like device, framework etc will be having multiple repositories inside them.
Git command like git add git commit git push etc at a time work on one repository mean on one .git folder. But a normal android mobile development project will be having almost 120 to 180 git repositories.
So question arise how to handle all 180 repositories. One way is ,go into all 180 repository manually perform our work; if we do like this our life will be miserable. So repo comes into picture.
So repo is a tool or set of scripts written in python to handle this situation. It has lot of command to make our life happy which are
1) repo init
2) repo sync
3) repo forall
4) repo prune
5) repo start
6) repo status
1) repo init:-
repo init -u url [options ]
Whenever we run repo init with some URL and option, it will create a .repo folder in your current directory. This .repo/ directory will contain Git repositories for our project; mean all .git repositories which I have mentioned above in projects folder. The .repo/ directory also contain manifest.xml, which is a symlink to the selected manifest in the .repo/manifests/ directory.
This manifest file contain the info of your all repositories, there path in source etc.
It something looks like this
So <project name="platform/cts" path="android/cts" />
Tell us that there is a project platform/cts and it can be found at android/cts path in the source.
To get this .repo folder we have to run repo init command. So let run us
$ repo init -u git://android.git.kernel.org/platform/manifest.git
This command will create a .repo folder containing repo specific and project specific files in your current directory. Here -u argument specifies a URL from which to retrieve a manifest repository.
To specify a revision, which is, a particular manifest-branch, use the -b option. For example:
$ repo init -u git://android.git.kernel.org/platform/manifest.git -b release-1.0
here revision is a name of the Git branch the manifest wants to track for this project.
Note: For all remaining Repo commands, the current working directory must either be the parent directory of .repo/ or a subdirectory of the parent directory.
repo sync [ project-list ]
Using repo init we installed the repo and got the project specific info but till yet we have not synchronized with the remote repository mean; we have not downloaded the source code till yet. So repo sync downloads new changes and updates the working files in your local environment. After successful repo sync, the code in specified projects will be up to date with the code in the remote repository.
You can specify project-list as a list of names or a list of paths to local source directories for the projects:
repo sync [proj1 proj2 ... projN]
Here proj1 might be kernel/lk or android/bootable/bootloader/lk
Like that we can define multiple project if want specific project files to sync with remote repository. Or give without any parameter if you want to sync files for all projects.
Generally Repo synchronization works like below
When we run repo sync,:
1. If the project has never been synchronized, then repo sync is equivalent to git clone. All branches in the remote repository are copied to the local project directory.
2. If the project has already been synchronized once, then repo sync is equivalent to:
git remote update
git rebase origin/branch
where 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, then no synchronization will occur for the project.
Mean if do repo sync in existing repo synced project it fetch the update from remote repository, then it rebase your current branch, here git remote update command is equivalent to git fetch. Basic difference between these two commands is:
git remote update fetch the update or new branch for all remote branches present in remote repository.
git fetch just fetch the changes for specified remote branch.
Sometime in git rebase operation results in merge conflicts, we need to use the normal Git commands (for example, git rebase --continue) to resolve those conflicts.
The repo sync command also updates the private repositories in the .repo/ directory.
repo start newbranchname [ project-list ]
when we do the repo sync , we got the copy of remote repository but branch of development is not specified till yet. Mean our commit will go to which branch is not specified or we are not on any branch till yet. So repo start command starts a new branch for development.
The project-list specifies which projects will participate in this topic branch. You can specify project-list as a list of names or a list of paths to local working directories for the projects:
repo start default [proj1 proj2 ... projN]
"." is a useful shorthand for the project in the current working directory.
repo status [project-list ]
Show the status of files with respect of current working directory, staging area and most recent commit on the branch (HEAD) in each project specified.
This command compares the working tree to the staging area (index) and the most recent commit on this branch (HEAD) in each project specified. Displays a summary line for each file where there is a difference between these three states.
repo status command shows the file status in current branch with two-letter code. Which is defined as?
In the first column, an uppercase letter indicates how the staging area differs from the last committed state.
|The file is added (brand new). Can only appear in the first column.|
M or m
|The file already exists but has been modified in some way.|
D or d
|The file has been deleted.|
|The file has been renamed. Can only appear in the first column. The new name is also shown on the line.|
|The file has been copied from another file. Can only appear in the first column. The source is also shown.|
|Only the file's mode (executable or not) has been changed. Can only appear in the first column.|
|The file has merge conflicts and is still unmerged. Can only appear in the first column.|
|The file state is unmodified. A hyphen in both columns means this is a new file, unknown to Git. After you run git add on this file, repo status will show A-, indicating the file has been added.|
In the second column, a lowercase letter indicates how the working directory differs from the index.
|-||new/unknown||not in index, in work tree|
|m||modified||in index, in work tree, modified|
|d||deleted||in index, not in work tree|
For example, if you edit the file hello.c within the hello world project without staging the changes, then repo status might show
Mean there is no change between staging area and repository, but file has been modified into working tree.
If you go on to stage the changes to hello.c by running git add, then repo status might show
Mean file hello.c has been modified in staging area with respect to repository and in next commit this change will go into repository.
-- secondprogam.c specifies that new untracked file exist in source code.
repo forall [ project-list ] -c command [ arg...]
Runs a shell command in each project.
Some time we want to run some git command in every git project. For that we can use repo forall.
For example if we want to get commit history of android project b/w v1.0 to v2.0 we can run this command
repo forall –c git log v1.0..v2.0
This command will run git log into all project repositories and will give us commit history between v1.o and v2.o
You can specify project-list as a list of names or a list of paths to local source directories for the projects
repo help [ command ]
Displays detailed help about a command.
repo prune [ project-list ]
basically this command is used to remove stale branches. Mean branches which are already merged and deleted from remote but not have been removed from the local.
we can specify project-list as a list of names or a list of paths to local source directories for the projects:
repo prune [proj1 proj2 ... projN]