Interrupted initial push leads to branch reference
Bug #189757 reported by
Aaron Bentley
This bug affects 1 person
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Bazaar |
Confirmed
|
High
|
canonical-bazaar |
Bug Description
I interrupted a push from a checkout, apparently at a critical moment. Then I pushed again, and the result was a branch reference, which points at the branch on my machine.
Steps to reproduce:
$ bzr init foo
$ bzr commit -m unchanged --unchanged foo
Committing to: /home/abentley/foo/
Committed revision 1.
$ bzr checkout foo bar --lightweight
$ bzr init baz
$ rm baz/.bzr/branch -R
$ bzr push -d bar baz
Created new branch.
$ cd baz
$ cd .bzr/branch
$ ls
format location
Changed in bzr: | |
importance: | Undecided → Critical |
description: | updated |
Changed in bzr: | |
importance: | Critical → High |
Changed in bzr: | |
status: | Triaged → Confirmed |
tags: | added: push |
Changed in bzr: | |
assignee: | nobody → canonical-bazaar (canonical-bazaar) |
To post a comment you must log in.
I can confirm that your steps do generate a branch reference in the target.
I'm guessing that this is happening because of the push fallback code.
Specifically, it used to be that doing "bzr push" would create the remote repository, but no branch. If you interrupted it, and tried to push again, it would fail, because it didn't have a branch, but it wasn't an empty directory, either.
I originally felt that push should create the remote branch, and then populate it, Robert felt that was a race condition. So now, it creates the repository, populates it, then the branch (as before). Except, if it finds a remote repo, it will then create a branch, and fetch into it (as I proposed, but only under extenuating circumstances, not as the default flow.)
The code in question is here:
warning( "Ignoring request for a stacked branch as repository "
"already exists at the destination location.") to.fetch( br_from. repository, revision_ id=revision_ id) clone(dir_ to, revision_ id=revision_ id) get_push_ location( ) is None or remember:
br_from. set_push_ location( br_to.base)
elif br_to is None:
# We have a repository but no branch, copy the revisions, and then
# create a branch.
if stacked_on is not None:
repository_
br_to = br_from.
note('Created new branch.')
if br_from.
So what is happening is that "br_from.clone()" on a BranchReference is creating a branch reference in the remote.
The problem may be as simple as using br_from.sprout() instead of .clone(), but sprout usually copies history, so I'm not sure how that works.
Also, we need to take some care because "br_from. sprout( to_bzrdir) " uses the 'to_bzrdir" as the one who decides the format. But as the target already existed, it probably isn't configured appropriately with the current branch format. (Normally, we do a sprout() after creating the bzrdir, and because we created the bzrdir we initialized it correctly, in this code path we *opened* the bzrdir, and have not set any of the format attributes.)