Repo tool notes

2019年2月25日

The official Repo Command Reference is extremely incomplete and misses many options. You have to use repo help init or go to https://gerrit.googlesource.com/git-repo/+/master/subcmds/init.py and read the source code.

repo clone repositories (and check out branch)

The command given by [1] is

repo init -u https://android.googlesource.com/platform/manifest -b android-8.1.0_r52
Repo sync

This is very slow! From the source code, we can find repo init accepts the option --depth, like git clone --depth. If you don’t need to see the previous history, set it to 1. repo sync accepts the option -c, which means that only update the current branch; --no-tags does not update tags; -j2 , executed with 2 threads.

[2] It is recommended to add --no-clone-bundle. According to [3], --no-clone-bundle is forbidden to download from CDN, but it will slow down when used. I guess maybe the bundle itself is the entire repository, because at the beginning it only needs depth=1, so it is disabled.

The optimized command is

repo init --depth 1 -u https://android.googlesource.com/platform/manifest -b android-8.1.0_r52
repo sync -c --no-tags -j4

Remember, if you want to get more history in the future, you can use git fetch --update-shallow, git fetch --shallow-since=15/11/2012, --deepen=<depth> and many other options.[4]

After checking this out, if you use git to view it in a separate repository, git will report “Not currently on any branch.”, according to [5], this is normal.

So how do you verify that repo really checks out every item to the android-8.1.0_r52 branch? Command

git rev-list -1 android-8.1.0_r52

or

git rev-parse android-8.1.0_r52^{}

can get the sha1 pointed to by the annotated tag.

Here, android-8.1.0_r52^{} indicates that android-8.1.0_r52 should be a tag, and ^{} means to get the content of the pointer until the type of the content is no longer a tag.[6]

The annotated tag itself is an object with sha1, which also has a pointer to the target version number.

Note that the lightweight tag itself is an alias for the version number, so ^{} can be omitted for getting the SHA1, ie.

git rev-parse 0.2.2

Of course, for consistency, and without distinguishing between lightweight labels and attached labels, you can always use git rev-parse tag^{}.

The following script can detect if the repo has checked out the correct branch. Call it by repo forall -c ~/Android-8.1.0/test-branch.sh android-8.1.0_r52.

#!/bin/bash

if [ "$(git rev-parse HEAD)" = "$(git rev-parse $1^{})" ]; then
	#echo "$(git rev-parse --show-toplevel) on branch $1"
	a=2
else
	echo "$(git rev-parse --show-toplevel) not on branch $1"
fi

Note, if you write it as repo forall -c test-branch.sh android-8.1.0_r52, repo will prompt “Got an error, terminating the pool: OSError: [Errno 2] No such file or directory”.

If the script doesn’t have #!/bin/bash,repo will prompt “Got an error, terminating the pool: OSError: [Errno 8] Exec format error”. Or you can specify bash,namely repo forall -c bash ~/Android-8.1.0/test-branch.sh android-8.1.0_r52.

repo reports the current branch

Repo cannot report the current branch.

repo switch branch

It is said that it can be used in existing repositories.

repo init -b <new_manifest_branch>
repo sync

will no re-clone the repositories.[7]

参考资料

  1. . Download source code. Android Open Source Project. [2019-02-22].
  2. . AOSP repo sync takes too long. . 2015-02-07 [2019-02-22].
  3. . Repo Introduction. . 2015- 06-25 [2019-02-22].
  4. . How to convert a Git shallow clone to a full clone?. . 2011-07-23 [2019-02-22].
  5. Magnus Bäck. . . 2014-10-17 [2019-02-22].
  6. . gitrevisions - Specifying revisions and ranges for Git. git. [2019-02-22].
  7. Jean-Baptiste Queru. how do I switch branches by repo. . 2013-02-19 [2019-02-22].