简体   繁体   English

在 Android Repo 项目中切换 Git 分支

[英]Switching Git branches inside an Android Repo project

I have a question about switching branches using repo .我有一个关于使用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.我的理解是,这将检出清单存储库的 foo 分支,然后检出清单中描述的 git 项目。

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?我的问题是,我可以在每次不执行 repo init 和 repo sync 的情况下切换分支,这样做有什么影响?

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 .我以前试过这个,它似乎有效,但有点奇怪,因为我现在已经检查了foo清单中的代码,但我当前的清单分支是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.我对与当前清单中描述的分支不同的分支的影响以及这可能如何影响我的工作流程感兴趣。

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. Tl; dr - 某些命令会做奇怪的事情。 Be careful when using repo sync and repo start . 使用repo syncrepo start时要小心。 Try to stick to plain git commands. 尝试坚持使用普通的git命令。 repo upload should work. repo upload应该工作。

The repo documentation says that repo sync is equivalent to repo文档说repo sync等同于

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

where BRANCH is the currently checked-out branch in the local project directory. 其中BRANCH是本地项目目录中当前签出的分支。 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. 但是,根据我自己的经验,repo还会根据当前清单中的内容搞乱该分支的上游跟踪信息。

To continue the example from above, git checkout foo-mytopic is, in fact, allowed, and will kind of behave appropriately. 为了继续上面的例子, git checkout foo-mytopic实际上是允许的,并且会表现得恰到好处。 Repo upload will push changes to the branch that foo-mytopic is tracking ( foo ), but repo sync would change the upstream tracking information. Repo upload会将更改推送到foo-mytopic正在跟踪的分支( foo ),但repo sync会更改上游跟踪信息。 In this situation, may be better to manually run git fetch origin and git rebase origin/<BRANCH> . 在这种情况下,最好手动运行git fetch origingit 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. repo init描述的清单(和分支)在重新执行repo syncrepo start之前不会再次发挥作用。

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> :我最近遇到一个条件,人们必须使用repo init -b <branch>来切换分支,而不是使用repo forall -c git checkout <branch>

  1. People currently working on the latest develop branch containing project A/B/C/D/E/F目前在包含项目A/B/C/D/E/F的最新develop分支上工作的人员
  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.而有一天我们需要回到release_1.0分支,那里只存在项目A/B/C ,还没有创建D/E/F

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".起初,我尝试repo forall -c git checkout release_1.0将工作区恢复到release_1.0但它失败了,说“项目 D/E/F 没有 release_1.0 分支”。

So the workspace looks like following when repo branches :因此,当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.除非我从我的工作区手动删除D/E/F否则编译肯定会失败。

But if when using repo init -b <branch>; repo sync但是如果使用repo init -b <branch>; repo sync repo init -b <branch>; repo sync , it works fine: repo init -b <branch>; repo sync ,它工作正常:

* release_1.0 | A,B,C

there is no more D,E,F.没有更多的 D、E、F。 They have been archived automatically by repo.它们已由 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).如果您想从release_1.0切换到develop (缺少D/E/F ,因为您从未从develop分支初始化和同步清单),您也会遇到类似的情况。

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

  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.回购同步为你做这两个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM