For a source code downloaded by repo init
and repo sync
, all projects and their branches are described in the manifest file specified by -m
. The manifest has a default
node and it has some attributes which could include revision="foo"
. For a project
node, if it has revision="some_ref_name"
or revision="some_sha1sum" upstream="some_ref_name"
, its default branch is some_ref_name
. If it does not have these attributes, the revision in the default node is used. Note that the ref could be a tag or any valid git ref other than a branch. The default node and the project nodes could be like
<default revision="some_ref_name" remote="origin" />
<project name="repo1" path="repo1" revision="some_ref_name" />
<project name="repo2" path="repo2" />
<project name="repo3" path="repo3" revision="afbdb1ba3bb7de1aa9c86e501d4ef635bdf05354" upstream="some_ref_name" />
However, by default, repo sync
checks out a detached HEAD from the ref head. A detached HEAD is more like an anonymous branch. Although it points at the same commit with the head of the ref at first, making a new commit based on the detached HEAD does not update the ref. Git commands like git branch
or git for-each-ref
do not help much.
If you want to get the default revision or upstream ref, the most reliable method is to parse the manifest file. In most cases, the manifest is a single xml file. It's easy to parse it or grep a regex in it. But the manifest file can have one or more nested manifest files. The repo
tool also supports local manifests. And in practice there are more cases which involve multiple manifest files. After you successfully run repo sync
, you could use repo manifest -r -o foo.xml
to create a single manifest file first. And then grep the project name or path and find its upstream.
Say you want to find the default ref of the project named bar
in foo.xml
.
grep -E 'name="bar"' foo.xml | grep -oP '(?<=upstream=")[^"]+(?=")'