在 Android Repo 项目中切换 Git 个分支

Switching Git branches inside an Android Repo project

我有一个关于使用 repo 切换分支的问题。我知道我可以像这样检查一个分支:

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

我的理解是,这将签出清单存储库的 foo 分支,然后签出清单中描述的 git 个项目。

我也明白我可以这样切换分支:

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

我的问题是,我是否可以在每次不执行 repo init & repo sync 的情况下切换分支,这样做有什么影响?

举个例子:

$ 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?

我以前试过这个,它似乎有效,但有点奇怪,因为我现在已经检查了 foo 清单中的代码,但我当前清单分支是 bar。位于与清单中描述的分支不同的分支上有什么影响?

注意:我已经阅读了 this,我认为我的问题有所不同。我知道如何切换分支。我对与当前清单中描述的分支不同的影响以及这可能如何影响我的工作流程感兴趣。

由于没有其他人能够回答这个问题,我做了更多的研究和实验。这是我的发现:

Tl;dr - 某些命令会做一些奇怪的事情。使用 repo syncrepo start 时要小心。尝试坚持简单的 git 命令。 repo upload 应该可以。

repo documentation 表示 repo sync 等同于

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

其中 BRANCH 是 本地项目目录中当前签出的分支。但是,根据我自己的经验,repo 也会弄乱该分支的上游跟踪信息基于当前清单中的内容。

继续上面的示例,git checkout foo-mytopic 实际上是允许的,并且会适当地表现。回购上传会将更改推送到 foo-mytopic 正在跟踪的分支 (foo),但回购同步会更改上游跟踪信息。在这种情况下,手动 运行 git fetch origingit rebase origin/<BRANCH>.

可能会更好

repo init 描述的清单(和分支)将不会再次发挥作用,直到 repo syncrepo start 为 运行。

我最近遇到一个情况,人们必须使用repo init -b <branch>来切换分支,而不是使用repo forall -c git checkout <branch>:

  1. 目前正在处理包含项目 A/B/C/D/E/F
  2. 的最新 develop 分支的人员
  3. 虽然有一天我们需要回到 release_1.0 分支,那里只有项目 A/B/CD/E/F 还没有创建。

起初,我尝试 repo forall -c git checkout release_1.0 将工作区恢复到 release_1.0,但失败了,提示“项目 D/E/F 没有 release_1.0 分支”。

因此当 repo branches:

时,工作区如下所示
* develop     | D,E,F
* release_1.0 | A,B,C

除非我从我的工作区中手动删除D/E/F,否则编译肯定会失败。

但是如果使用repo init -b <branch>; repo sync,它工作正常:

* release_1.0 | A,B,C

没有D,E,F了。它们已由 repo 自动存档。

如果您想从 release_1.0 切换到 develop,您也会遇到类似的情况(D/E/F 丢失,因为您从未从 [=14] 初始化和同步清单=]分支)。

因此 repo forall -c git checkout <branch> 无法处理不同分支中的清单之间存在存储库更改(从清单中添加或删除)的情况,因为使用多个存储库切换主题分支意味着两件事:

  1. 使您的工作区仅包含该版本所需的存储库(不多也不少)。
  2. 检查他们的分支到你想要的那个。

repo sync 为您完成这两项工作。