Strange behavior on local branches with repo sync, due to my manifest

3,462 views
Skip to first unread message

Propane13

unread,
Jan 20, 2012, 3:22:45 PM1/20/12
to Repo and Gerrit Discussion
Hello!

This may seem like a rookie question, but I think it's valid.
I'm going to be detailed in the steps for reproducing.


My manifest has this line:

<default revision="refs/heads/master"
remote="origin" />

Now, let's say that I have done a repo sync, and I've got a bunch of
projects.

<project path="projects/firstProject" name="firstProject" />
<project path="projects/secondProject" name="secondProject" />

I've got my projects, and everything's looking great.

Next, I need to look at a bugfix to a branch that was made months ago
in firstProject.
So, I do:
cd ~/repo_root/projects/firstProject
git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/1.0.0

Next, I do my checkout to see what's on the 1.0.0 branch.
git checkout 1.0.0
Previous HEAD position was b71a548... (some comment)
Branch 1.0.0 set up to track remote branch 1.0.0 from origin.
Switched to a new branch '1.0.0'

Wonderful. Everything looks fine to me, so I forget about this awhile.

A few days pass, and then I find out that I need to add a third
project.
<project path="projects/thirdProject" name="thirdProject" />

Once that's added, I do a new repo sync.

Uh-oh; something bad happens. Since firstProject was on branch 1.0.0
instead of master, this message comes up at the end of my sync:

projects/firstProject/: manifest switched refs/heads/1.0.0...refs/
heads/master
projects/firstProject/: discarding 3 commits removed from upstream

Now, oddly, my 1.0.0 local branch is tracking remotes/origin/master,
not remotes/origin/1.0.0.
That's totally wrong-- it's like it broke its current tracking to do
something incorrect.

This is a little confusing for me.

I kind of want the checked-out branch to track to whatever remote it
was already specified to.
So, if firstProject was pointing to 1.0.0, and secondbranch was
pointing to master, both should "git fetch" and "git rebase remotes/
origin/(branch_i_am_on)"

So, the questions I have are:
1) Am I crazy, or is there something that I can put in the manifest to
track branches to their branches respectively, so this doesn't happen?
2) Is there a way to not specify a default revision in the manifest,
and still have it function without python errors?
3) I guess if 2 isn't possible, I could maybe have it tie to a default
tag across the board-- that's something that won't track at all; can a
tag be done as the default revision?

I'm hoping I'm just missing something.
Suggestions? Surely someone else finds this a little annoying besides
just me.

Thanks!
-John

Magnus Bäck

unread,
Jan 22, 2012, 5:14:54 AM1/22/12
to Repo and Gerrit Discussion
On Friday, January 20, 2012 at 21:22 CET,
Propane13 <johnk...@gmail.com> wrote:

> This may seem like a rookie question, but I think it's valid.
> I'm going to be detailed in the steps for reproducing.
>
>
> My manifest has this line:
>
> <default revision="refs/heads/master"
> remote="origin" />

"master" would've been enough, but "refs/heads/master" is fine too.

> Now, let's say that I have done a repo sync, and I've got a bunch of
> projects.
>
> <project path="projects/firstProject" name="firstProject" />
> <project path="projects/secondProject" name="secondProject" />
>
> I've got my projects, and everything's looking great.
>
> Next, I need to look at a bugfix to a branch that was made months ago
> in firstProject.
> So, I do:
> cd ~/repo_root/projects/firstProject
> git branch -a
> * master
> remotes/origin/HEAD -> origin/master
> remotes/origin/master
> remotes/origin/1.0.0

Hmm. This doesn't quite look like what I'd expected. Have you already
created a topic branch named "master"? What's with the origin/HEAD
symbolic ref? I would've expected a symbolic ref m/master (or whatever
your manifest branch is called) pointing to origin/master.

> Next, I do my checkout to see what's on the 1.0.0 branch.
> git checkout 1.0.0
> Previous HEAD position was b71a548... (some comment)
> Branch 1.0.0 set up to track remote branch 1.0.0 from origin.
> Switched to a new branch '1.0.0'
>
> Wonderful. Everything looks fine to me, so I forget about this awhile.
>
> A few days pass, and then I find out that I need to add a third
> project.
> <project path="projects/thirdProject" name="thirdProject" />
>
> Once that's added, I do a new repo sync.
>
> Uh-oh; something bad happens. Since firstProject was on branch 1.0.0
> instead of master, this message comes up at the end of my sync:
>
> projects/firstProject/: manifest switched refs/heads/1.0.0...refs/
> heads/master

This doesn't make sense. According to the information you've given us,
the manifest has pointed to refs/heads/master all the time.

> projects/firstProject/: discarding 3 commits removed from upstream
>
> Now, oddly, my 1.0.0 local branch is tracking remotes/origin/master,
> not remotes/origin/1.0.0.
> That's totally wrong-- it's like it broke its current tracking to do
> something incorrect.

Checked out topic branches are rebased to the current upstream, so the
behavior you've seen is expected. If you don't want a topic branch to be
rebased, make sure it isn't checked out (run "repo sync -d" to detach
all topic branches).

> This is a little confusing for me.
>
> I kind of want the checked-out branch to track to whatever remote it
> was already specified to.
> So, if firstProject was pointing to 1.0.0, and secondbranch was
> pointing to master, both should "git fetch" and "git rebase remotes/
> origin/(branch_i_am_on)"

Well, that's just not how Repo works. It seems you're looking at Repo's
topic branches as long-lived branches where you make various (in this
case) maintenance bug fixes for a period of maybe months, and with that
view I agree that what you want would've made sense. However, the
intention is that topic branches are short-lived branches for specific
corrections that are to be uploaded to just about any branch. Hence,
1.0.0 doesn't really make sense as a topic branch name, but
fix-overflow-bug does.

> So, the questions I have are:
> 1) Am I crazy, or is there something that I can put in the manifest to
> track branches to their branches respectively, so this doesn't happen?

Nope.

> 2) Is there a way to not specify a default revision in the manifest,
> and still have it function without python errors?

Why would you want to do that? Each project must be bound to a revision.

> 3) I guess if 2 isn't possible, I could maybe have it tie to a default
> tag across the board-- that's something that won't track at all; can a
> tag be done as the default revision?

Sure, just put refs/tags/nameoftag in the revision field. Note that
"repo upload" won't work if you do this (since you can't upload changes
to a tag or a SHA-1).

--
Magnus Bäck Opinions are my own and do not necessarily
SW Configuration Manager represent the ones of my employer, etc.
Sony Ericsson

Propane13

unread,
Jan 23, 2012, 4:47:07 PM1/23/12
to Repo and Gerrit Discussion
Thanks for getting back to me.

I'll try to address your points-- they are valid.

For the git branch -a, you're right. I do think it's fishy, so I'm
going to do a fresh clone, and share what I have:

I'm doing this:
./repo init -m manifest.xml -u ssh://<username>@<gerrit_server>:29418/manifest.git
./repo sync
./repo forall -c "git branch --track master remotes/origin/master"
./repo forall -c "git checkout master"

Then, I run this:
cd ~/repo_root/projects/firstProject
git branch -a

Here's what I see:
* master
remotes/m/master -> origin/master
remotes/origin/1.0.0
remotes/origin/1.0.1

So, that's good.

It's at this point that I need to specify that as you guessed it, I am
adapting repo/git to meet the needs of my current employer. I came
from an android/git background, and understand that the Google model
for Android projects has certain recommendations for best practices.
However, in some companies/organizations, the shoe doesn't fit on all
feet the same way.

The methodology when I came into the picture at this organization was
to have long-lasting branches that are forks in our code. Most people
will be on master for the majority of their work, but we do maintain
"maintenance branches" that may need to be updated with bugfixes on
occasion. These branches could last for up to 6 months. Now, if I
remember right, android work usually has a different manifest for each
code fork-- there's a manifest for IceCreamSandwich, and one for
Honeycomb. For our needs, it seems to make sense to just use one
manifest, but it sounds like we'll hit the weird rebase behavior in
the repo tool when we do that.

It was hard enough to get the organization to accept git and repo;
it'd be harder still to change build processes and ideas, That's why
I'm thinking of submitting a patch to repo so that it can handle both
methodologies (short topic branches vs. longer ones).

So, I'll walk through this again (this is boring, but I wanted to add
more detail if anyone cares):

git checkout 1.0.0
Branch 1.0.0 set up to track remote branch 1.0.0 from origin.
Switched to a new branch '1.0.0'

If I open gitk --all, I see that 1.0.0 local branch is on the same
SHA1 as remotes/origin/1.0.0.
I will note that 1.0.0 was a branch created a month ago, and uploaded
to a gerrit server. It is a definite fork, not planned to merge into
master.

Here's my current git branch -a
* 1.0.0
master
remotes/m/master -> origin/master
remotes/origin/1.0.0
remotes/origin/1.0.1
remotes/origin/master

git remote show origin

warning: more than one branch.master.remote
* remote origin
Fetch URL: ssh://<gerrit_server>:29418/firstProject
Push URL: ssh://<gerrit_server>:29418/firstProject
HEAD branch: master
Remote branches:
1.0.0 tracked
1.0.1 tracked
master tracked
Local branches configured for 'git pull':
1.0.0 merges with remote 1.0.0
master merges with remote master
and with remote master
Local refs configured for 'git push':
1.0.0 pushes to 1.0.0 (up to date)
master pushes to master (local out of date)

Then, all I do is change the manifest. I add white space and push it
back.

Next, I do repo sync

I get this message at the end:

projects/firstProject/: manifest switched refs/heads/1.0.0...refs/
heads/master
projects/firstProject/: discarding 3 commits removed from upstream

Afterwards, I open gitk --all, and:
- 1.0.0 branch is on the same commit as remotes/origin/master and
remotes/m/master, and completely moved away from remotes/origin/1.0.0.

git remote show origin
* remote origin
Fetch URL: ssh://<gerrit_server>:29418/firstProject
Push URL: ssh://<gerrit_server>:29418/firstProject
HEAD branch: master
Remote branches:
1.0.0 tracked
1.0.1 tracked
master tracked
Local branches configured for 'git pull':
1.0.0 merges with remote master
master merges with remote master
and with remote master
Local refs configured for 'git push':
1.0.0 pushes to 1.0.0 (local out of date)
master pushes to master (local out of date)

The push location stayed the same, but we've changed from:
1.0.0 merges with remote 1.0.0
to:
1.0.0 merges with remote master

Now, it sounds like this is as designed, from what you've written.

> Well, that's just not how Repo works. It seems you're looking at Repo's
> topic branches as long-lived branches where you make various (in this
> case) maintenance bug fixes for a period of maybe months, and with that
> view I agree that what you want would've made sense. However, the
> intention is that topic branches are short-lived branches for specific
> corrections that are to be uploaded to just about any branch. Hence,
> 1.0.0 doesn't really make sense as a topic branch name, but
> fix-overflow-bug does.

So, yeah, our implementation of process doesn't seem to match the
tool.
The 2 options here are-- modify the tool, or get the organization to
change.
The easier method seems to be to modify repo for our case.

> > So, the questions I have are:
> > 1) Am I crazy, or is there something that I can put in the manifest to
> > track branches to their branches respectively, so this doesn't happen?
>
> Nope.

Based on this, I'm thinking to make a local patch to repo.
I'm thinking of making a change to the manifest that repo could
interpret.

One idea is:

<default revision="MYLOCALBRANCH"
remote="origin" />

and the other is:

<default revision="refs/heads/master" rebaseBranchToManifest="no"
remote="origin" />


The thought would be to tweak repo such that if there's some special
wildcard in there, "MYLOCALBRANCH", or a special flag to tell it not
to rebase everything to the manifest that's not checked out, it'll
rebase to the current branch to its current remote that matches that
branch.

I'll think on this more; there may be a less-invasive and more-
intuitive way to set a flag for this.

> > 2) Is there a way to not specify a default revision in the manifest,
> > and still have it function without python errors?
>
> Why would you want to do that? Each project must be bound to a revision.

Yeah, this was a plan B of sorts; not the best of ideas, otherwise the
rebase of master-to-master changes is completely shot anyway.
Forget I even said that.

So, I'll do some tweaking and share what I come up with for the repo
tool.
If it's not too invasive, I'll submit it back for consideration; I'm
not sure that android developers would have any use for such a
feature, but it sounds like this might be a little tweak that could
make repo more globally usable by other users that have different
branching strategies.

Thanks a lot!

-John

Magnus Bäck

unread,
Jan 24, 2012, 2:45:10 AM1/24/12
to Repo and Gerrit Discussion
On Monday, January 23, 2012 at 22:47 CET,
Propane13 <johnk...@gmail.com> wrote:

> For the git branch -a, you're right. I do think it's fishy, so I'm
> going to do a fresh clone, and share what I have:
>
> I'm doing this:
> ./repo init -m manifest.xml -u ssh://<username>@<gerrit_server>:29418/manifest.git

You're working too hard. Use an insteadOf block in your ~/.gitconfig or
a host alias in your ~/.ssh/config to avoid having to type username and
port every time. Put Repo in your $PATH. And why call the manifest
manifest.xml instead of default.xml, forcing users to use the -m option
all the time?

> ./repo sync
> ./repo forall -c "git branch --track master remotes/origin/master"
> ./repo forall -c "git checkout master"

The latter two commands can be replaced by "repo start master", given
that your manifest points to the master branch on all gits.

> Then, I run this:
> cd ~/repo_root/projects/firstProject
> git branch -a
>
> Here's what I see:
> * master
> remotes/m/master -> origin/master
> remotes/origin/1.0.0
> remotes/origin/1.0.1
>
> So, that's good.

Yup.

> It's at this point that I need to specify that as you guessed it, I am
> adapting repo/git to meet the needs of my current employer. I came
> from an android/git background, and understand that the Google model
> for Android projects has certain recommendations for best practices.
> However, in some companies/organizations, the shoe doesn't fit on all
> feet the same way.

While Repo was designed for use with Android, I don't think there's
anything that makes it inherently unsuited for other ways of working.

> The methodology when I came into the picture at this organization was
> to have long-lasting branches that are forks in our code. Most people
> will be on master for the majority of their work, but we do maintain
> "maintenance branches" that may need to be updated with bugfixes on
> occasion. These branches could last for up to 6 months. Now, if I
> remember right, android work usually has a different manifest for each
> code fork-- there's a manifest for IceCreamSandwich, and one for
> Honeycomb. For our needs, it seems to make sense to just use one
> manifest, but it sounds like we'll hit the weird rebase behavior in
> the repo tool when we do that.

Repo uses the manifest to decide which branch to track and where to
upload changes. If you diverge from this you should be prepared for
discovering all sorts of nuisances. You might be able to fix some of
them, but for the rest the tool will just appear awkward.

It's not unusual to have longlived branches, and the evidence you've
presented so far doesn't indicate that you have other needs than Google
or other users of Gerrit. You're not special, you're just different.

You have explained *what* you want to change in Repo and you have
some thoughts of *how*, but the *why* still eludes me. What special
way of working needs to be supported, and what advantages would it
have? Right now it -- honestly -- sounds like it's a feature to support
change-reluctant organizations who got on the wrong track from the
beginning and want to avoid the slight mindset change of actually using
the manifest for what it's meant to be used for.

On the other hand, tools should generally be flexible enough to support
more than one way of working, although I think the different ways should
be sufficiently different and unique to have their own strengths and
weaknesses.

[...]

> So, yeah, our implementation of process doesn't seem to match the
> tool.
> The 2 options here are-- modify the tool, or get the organization
> to change.
> The easier method seems to be to modify repo for our case.

If it's possible to do in a clean way so that you get upstream
acceptance then it might be worth it for you, but beware if you
need to fork Repo itself. The cost for that would be high.

> Based on this, I'm thinking to make a local patch to repo.
> I'm thinking of making a change to the manifest that repo could
> interpret.
>
> One idea is:
>
> <default revision="MYLOCALBRANCH"
> remote="origin" />
>
> and the other is:
>
> <default revision="refs/heads/master" rebaseBranchToManifest="no"
> remote="origin" />
>
>
> The thought would be to tweak repo such that if there's some special
> wildcard in there, "MYLOCALBRANCH", or a special flag to tell it not
> to rebase everything to the manifest that's not checked out, it'll
> rebase to the current branch to its current remote that matches that
> branch.
>
> I'll think on this more; there may be a less-invasive and more-
> intuitive way to set a flag for this.

It sounds like it should be a user preference rather than a per-manifest
(or per-project) setting.

[...]

> So, I'll do some tweaking and share what I come up with for the repo
> tool.
> If it's not too invasive, I'll submit it back for consideration; I'm
> not sure that android developers would have any use for such a
> feature, but it sounds like this might be a little tweak that could
> make repo more globally usable by other users that have different
> branching strategies.

I'm sorry, but it worries me greatly that you think this has anything
to do with branching strategies. You haven't said anything that would
suggest that it's your branching strategy that's requiring this change
in Repo.

Propane13

unread,
Jan 24, 2012, 5:07:43 PM1/24/12
to Repo and Gerrit Discussion
> > For the git branch -a, you're right. I do think it's fishy, so I'm
> > going to do a fresh clone, and share what I have:
>
> > I'm doing this:
> > ./repo init -m manifest.xml -u ssh://<username>@<gerrit_server>:29418/manifest.git
>
> You're working too hard. Use an insteadOf block in your ~/.gitconfig or
> a host alias in your ~/.ssh/config to avoid having to type username and
> port every time. Put Repo in your $PATH. And why call the manifest
> manifest.xml instead of default.xml, forcing users to use the -m option
> all the time?

I agree that I can optimize steps. These are the "for dummies" steps
that prevent people from pulling me to their cube to debug weird
config files; longer term, after users were able to crawl in git,
everybody here now has their own gitconfig and ssh config files.

It's just my opinion, but default.xml is a really um... non-
descriptive name for the manifest.
Sure; long-time repo users are used to it, but new engineers have no
idea what a manifest is.
Last time I did a migration to git, I left it at default.xml, and I
constantly had the "where is the manifest file located-- I forgot"
question, and to prevent that, I just renamed it with -m. People
usually alias "repo init", so it doesn't really cost anything in their
time, but it has saved me some sanity.

Anyway, all steps get to the same place.

> > ./repo sync
> > ./repo forall -c "git branch --track master remotes/origin/master"
> > ./repo forall -c "git checkout master"
>
> The latter two commands can be replaced by "repo start master", given
> that your manifest points to the master branch on all gits.

Thanks! I'll be sure to use this.

> It's not unusual to have longlived branches, and the evidence you've
> presented so far doesn't indicate that you have other needs than Google
> or other users of Gerrit. You're not special, you're just different.
>
> You have explained *what* you want to change in Repo and you have
> some thoughts of *how*, but the *why* still eludes me. What special
> way of working needs to be supported, and what advantages would it
> have? Right now it -- honestly -- sounds like it's a feature to support
> change-reluctant organizations who got on the wrong track from the
> beginning and want to avoid the slight mindset change of actually using
> the manifest for what it's meant to be used for.
>
> On the other hand, tools should generally be flexible enough to support
> more than one way of working, although I think the different ways should
> be sufficiently different and unique to have their own strengths and
> weaknesses.

Ok, I guess it's time to get into branch strategy to give some insight
into why things might be different in different organizations.

I don't think I would consider my organization to be change-
reluctant. If we were, git and repo never would have been fitted into
our process.
We'd probably continue using subversion until I became that cranky guy
at the bar that talked about the "good old days" where "people at my
last job did it right and used git".

I think the problem stems from a few other factors.
If I remember right, making Android-based releases was easy:
./repo forall -c "git tag RELEASE0001"

But, what happens if you have a release process where you don't want
to release/tag everything at the same time?
It's not crazy. It's just not what embedded software looks like. For
embedded software, you kind of release everything together, and build
them all together into a single binary (or a few binaries). What
happens, though, if your projects don't all release together?
Blasphemy you say? Nah, it's just not the embedded world.

You could have 50 projects, and 5 of them are all interdependent and
make a final jarfile that's releaseable. Many projects can make their
own independent jarfile. In these cases, you can have some engineers
saying at the end of a release cycle "let's release projects A, B, and
C, but not release projects D through Z, since they're not ready". I
don't think it's fair to force an organization to have to make all of
its deliverables in this case line up-- that's not necessarily a fast-
pased development methodology. That generally would mean that you can
only really release at the pace of the slowest component, which is not
ideal.

So, in those cases, I just want to make a new tag to a few projects at
a time; not all of them. That's doable without repo forall (I can
apply individually), but another wrench in the system is maven. If
you're not familiar with maven, then there's a whole world of
weirdness and dependency management that is very interesting and cool,
but it does have its own rule set that must be followed to be
effective.

(Note-- the below paragraph may not make sense to people who don't
know how maven works)
So, if I want to just release "project A" this month, I have to do
some special things. Typically, I'd use the maven release plugin;
that creates a branch, and it bumps the version number of my current
component number up a level (so, from 1.0.0-SNAPSHOT to 1.0.1-
SNAPSHOT). Any dependencies that were snapshot dependencies (which
were likely master) become their last released component versions on
that branch, whereas the master branch stays on the snapshot
versions. The benefit here is that in a maven model, if you have a
bugfix, you apply it to the branch, and apply a new tag to that
branch. And, if you want to work on master, you still can, and that
has the latest snapshot dependencies.

In short, we like the ability to piecemeal release components, and to
use maven for dependency management.
If we only release a new jar for component A, we want a branch
available for bugfixes on that branch. People work on master, and put
bugfixes in component A on occasion when there are problems found in
A's deployed code.

I guess one solution is to make a bunch of manifests for each release,
and to have developers use different manifests for each one. But,
that can add a lot of confusion to a bunch of developers that are new
to git; I can see them making a lot of mistakes. Most of them
generally will work on master, but the old release branches will live
on, in case of bugfixes. And, they definitely should not be rebased--
they are markers of a point in time.

This may sound like crazy talk, but it makes sense, and it's working
very well as a process.

I do like repo- a lot. It solves a lot of problems for things that
need to be done on multiple repositories at the same time, which is
better than any bash script I could write and be forced to maintain.
I even felt like I was wearing a carrot suit when I pitched it to
management-- I got a lot of confused looks.
But, now they're into it, and we have it, and it's working great--
mostly. The only single problem that we have is that if I just happen
to check out an old legacy branch, and it does the weird things
mentioned in previous posts. We're not using repo upload or a
majority of the repo commands; honestly, we just don't need them.
But, the synching and "repo forall" commands are wonderful.

It would be really nice if it didn't try to upmerge our legacy
branches. I think I have no choice but to fork the repo tool, but I
also want to be good to the community and offer such a changeset back
to google if they would want it. It seems like a simple-ish change,
but I could understand if it's not something they'd want to be owners
of, since it doesn't follow their model. However, such a changeset
would benefit other maven-based organizations that release projects on
their own timelines, like mine. In this case, I think it makes the
most sense to modify the tool for the organization. It's really quite
a simple change in concept, really.

I hope some of this makes sense. I'm starting to look into the python
to see what I can do to make things rebase to your current branch
that's checked. Since the only 2 options are to rebase to the
manifest's branch or to skip rebasing altogether, those aren't going
to cut it. :) Any hints in that area would be appreciated.

Regards,
-John

Propane13

unread,
Jan 26, 2012, 2:13:42 PM1/26/12
to Repo and Gerrit Discussion
Ok, if anyone ever reads this thread further or googles it, I wanted
to at least share the solution that seems to be working (we're still
testing),
Surely someone besides me will have a need to not branch/tag all
projects together, and may also be using maven and be under its
restrictions.

Our solution patch to repo is in file:
.repo/repo/project.py

Branching out of tag v1.7.8.2 (commit
c9571423f843340de19ef576ccaa418ac72fdb58)

Line 1106, change:
self._ResetHard(revid)
to:
self._ResetHard(branch.merge)

This is in this try-block, under the local_changes elif.
Here's the specific block changed:

if cnt_mine > 0:
def _dorebase():
self._Rebase(upstream = '%s^1' % last_mine, onto = revid)
self._CopyFiles()
syncbuf.later2(self, _dorebase)
elif local_changes:
try:
self._ResetHard(revid)
self._CopyFiles()
except GitError, e:
syncbuf.fail(self, e)
return
else:
def _doff():
self._FastForward(revid)
self._CopyFiles()
syncbuf.later1(self, _doff)

Again, this "seems to be working"; master rebases on remotes/origin/
master, and local branches seem to be rebasing to their remote/origin
version.

Of course, if I'm full of crap, or if testing shows us any problems,
I'll post them here.

Obviously, If this ever gets in as a feature, it'd need a flag for
enabling/disabling.
However, I'm not sure that repo owners would want this fix, and I am
not sure how to submit it anyway.
If anyone thinks there's value to this, I'd be willing to try to make
a configurable solution to submit back.

But, at a minimum, I just wanted to help those who google and have the
same problems that I did.
It drives me crazy when I find a help thread somewhere with no
solution or workaround posted. :)

Thanks and regards,
-John

Propane13

unread,
Jan 26, 2012, 4:28:10 PM1/26/12
to Repo and Gerrit Discussion
Nuts-- this is close, but doesn't work.
I need to hit all 3 conditions in the if-block, and I need to do more
python-wizardry.
Wnyway, what's posted is enough to get someone poking in the right
place.

Joey J. Hwang

unread,
Apr 1, 2012, 9:41:51 PM4/1/12
to repo-d...@googlegroups.com
I have same problem. 
 
Uh-oh; something bad happens.  Since firstProject was on branch 1.0.0
instead of master, this message comes up at the end of my sync:

projects/firstProject/: manifest switched refs/heads/1.0.0...refs/
heads/master
projects/firstProject/: discarding 3 commits removed from upstream

 
I've googled, but can't find any article belong to this. 


If the above saying is true, local 1.0.0 branch should be rebased the 1.0.0 that is remote tracking branch.
But, in my test, it's not working such like that. My topic branch rebased to manifest's default revision.

I think it is need to be fixed, isn't it?

Andrey Polyakov

unread,
Jun 12, 2015, 4:23:37 AM6/12/15
to repo-d...@googlegroups.com, zooy...@gmail.com
This is still an issue. Any solution? Having feature branches always being rebased onto master does not seem like a workflow that makes sense to me. What if you have multiple people working on that branch?

Magnus Bäck

unread,
Jun 12, 2015, 6:41:58 AM6/12/15
to repo-d...@googlegroups.com
On Thursday, June 11, 2015 at 22:33 CEST,
Andrey Polyakov <apol...@demonware.net> wrote:

> This is still an issue. Any solution? Having feature branches always
> being rebased onto master does not seem like a workflow that makes
> sense to me.

Repo uses the manifest's revision attribute to determine the upstream
remote and branch. It might make sense to change this and have it pay
attention to the upstream branch according to .git/config, but it's
totally conceivable that we'd run into other corner cases.

> What if you have multiple people working on that branch?

Isn't this thread about local branches, which Repo calls topic branches?
You never have more than one user working on them.

--
Magnus Bäck | Software Engineer, Development Tools
magnu...@sonymobile.com | Sony Mobile Communications

Константин Беклемишев

unread,
Jun 23, 2015, 9:30:08 AM6/23/15
to repo-d...@googlegroups.com

> What if you have multiple people working on that branch?

Isn't this thread about local branches, which Repo calls topic branches?
You never have more than one user working on them.


No it's about when you want to deal with topic branches for a remote branch, which is not the default revision for your current project.

It's ok, when your branch was created by repo start command.
But if you work with another branch, which must track remote branch that differs the default revision,
it will be forcibly switched to the default revision anyway.

I want to be able have branches, which track not only the default revision.


Repo forces the revision for absolutely all tracking branches
and it's done every time you do repo sync.
May be it's enough to generate .git/config only once?

We don't want to patch repo, so current solutions are:
1. use 'repo sync' only the first time and further use 'git pull' instead,
2. have a lot of manifest revisions for each extra branch in the git-project and for each git-project(!) with extra branches

PS Besides repo upload always works well.

hemp...@gmail.com

unread,
Mar 16, 2016, 8:31:45 AM3/16/16
to Repo and Gerrit Discussion
I don't know if this will help anyone else, but I was experiencing this/a similar problem.

We have a project where the revision is set to "release" but whenever we are checked out onto master and do a repo sync, it changes the remote tracking branch to release.

To solve this, I added rebase="false" as an attribute to the project in the manifest.xml and modified project,py as so..

diff --git a/project.py b/project.py
index 456e9de..8e563d4 100644
--- a/project.py
+++ b/project.py
@@ -1307,7 +1307,7 @@ class Project(object):
 
     # If the upstream switched on us, warn the user.
     #
-    if branch.merge != self.revisionExpr:
+    if branch.merge != self.revisionExpr and self.rebase:
       if branch.merge and self.revisionExpr:
         syncbuf.info(self,
                      'manifest switched %s...%s',
@@ -1318,7 +1318,7 @@ class Project(object):
                      'manifest no longer tracks %s',
                      branch.merge)
 
-    if cnt_mine < len(local_changes):
+    if cnt_mine < len(local_changes) and self.rebase:
       # Upstream rebased.  Not everything in HEAD
       # was created by this user.
       #
@@ -1327,7 +1327,7 @@ class Project(object):
                    len(local_changes) - cnt_mine)
 
     branch.remote = self.GetRemote(self.remote.name)
-    if not ID_RE.match(self.revisionExpr):
+    if not ID_RE.match(self.revisionExpr) and self.rebase:
       # in case of manifest sync the revisionExpr might be a SHA1
       branch.merge = self.revisionExpr
     branch.Save()
@@ -1339,7 +1339,8 @@ class Project(object):

       syncbuf.later2(self, _dorebase)
     elif local_changes:
       try:
-        self._ResetHard(revid)
+        #self._ResetHard(revid)
+        self._ResetHard(branch.merge)
         self._CopyAndLinkFiles()
       except GitError as e:
         syncbuf.fail(self, e)
(END)

The first two changes prevent the prints saying "manifest switchied master...release" and "discarding %d commits removed from upstream". The magic is in the second and third change.
Thanks to Propane13 for the last change.

Hope this helps others on their way in the future.
Reply all
Reply to author
Forward
0 new messages