Switching Git branches inside an Android Repo project

2.8k views Asked by At

I have a question about switching branches using repo. I know that I can checkout a branch like this:

$ repo init ... -b foo
$ repo sync

My understanding is that this will checkout the foo branch of the manifest repository, and then check out the git projects as described in the manifest.

I also understand that I can switch branches like this:

$ repo init ... -b bar
$ repo sync -d

My question is, can I switch branches without doing repo init & repo sync each time, and what are the implications of doing so?

Let me illustrate with an example:

$ repo init ... -b foo
$ repo sync -d
$ repo start foo-mytopic proj1 proj2
 ... make some commits ...
$ repo upload -t
$ repo init ... -b bar
$ repo sync -d
$ repo start bar-topic proj1 proj3
$ repo upload -t
$ cd proj1
$ git checkout foo-mytopic # IS THIS ALLOWED?

I've tried this before, and it seems to work, but it's a bit strange because I have now checked out code that was in the foo manifest, but my current manifest branch is bar. What are the implications of being on a different branch than that described in the manifest?

Note: I've read this, and I think my question is different. I know how to switch branches. I'm interested in the implications of being on a different branch than the one described in the current manifest and how this might affect my workflow.

2

There are 2 answers

0
mkasberg On BEST ANSWER

Since no one else was able to answer this, I did some more research and experimentation. Here is what I have found:

Tl;dr - Certain commands will do weird things. Be careful when using repo sync and repo start. Try to stick to plain git commands. repo upload should work.

The repo documentation says that repo sync is equivalent to

$ git fetch origin
$ git rebase origin/<BRANCH>

where BRANCH is the currently checked-out branch in the local project directory. However, based on my own experience, repo will also mess with the upstream tracking information for that branch based on what is in the current manifest.

To continue the example from above, git checkout foo-mytopic is, in fact, allowed, and will kind of behave appropriately. Repo upload will push changes to the branch that foo-mytopic is tracking (foo), but repo sync would change the upstream tracking information. In this situation, may be better to manually run git fetch origin and git rebase origin/<BRANCH>.

The manifest (and branch) described by repo init will not come into play again until repo sync or repo start is run.

0
lanyusea On

I met a condition recently that people have to use repo init -b <branch> to switch branch instead of using repo forall -c git checkout <branch>:

  1. People currently working on the latest develop branch containing project A/B/C/D/E/F
  2. While one day we need to go back to release_1.0 branch where there only exist project A/B/C, D/E/F are not created yet.

At first, I try repo forall -c git checkout release_1.0 to get the workspace back to release_1.0 but it fails by saying "project D/E/F has no release_1.0 branch".

So the workspace looks like following when repo branches:

* develop     | D,E,F
* release_1.0 | A,B,C

It will definitely fail in compiling unless I delete the D/E/F manually from my workspace.

But if when using repo init -b <branch>; repo sync, it works fine:

* release_1.0 | A,B,C

there is no more D,E,F. They have been archived automatically by repo.

Also you will meet a similar condition if you want to switch from release_1.0 to develop (D/E/F is missing since you never init and sync the manifest from the develop branch).

So the repo forall -c git checkout <branch> cannot handle the condition when there are repository changes (added or removed from manifest) between the manifests in different branches because the topic branch switching with multi repositorys means two things:

  1. make your workspace only contains the repository needed in that version (no more, no less).
  2. check out their branches into the one you want.

repo sync do both of these for you.