Merge lp:~spiv/bzr/sprout-does-not-reopen-repo into lp:bzr
| Status: | Merged |
|---|---|
| Approved by: | Vincent Ladeuil on 2010-12-14 |
| Approved revision: | 5545 |
| Merged at revision: | 5570 |
| Proposed branch: | lp:~spiv/bzr/sprout-does-not-reopen-repo |
| Merge into: | lp:bzr |
| Diff against target: |
550 lines (+133/-47) 10 files modified
bzrlib/branch.py (+45/-22) bzrlib/bzrdir.py (+7/-3) bzrlib/controldir.py (+26/-5) bzrlib/remote.py (+27/-11) bzrlib/tests/blackbox/test_branch.py (+1/-1) bzrlib/tests/test_branch.py (+1/-1) bzrlib/tests/test_bzrdir.py (+7/-0) bzrlib/tests/test_foreign.py (+4/-2) doc/en/release-notes/bzr-2.3.txt (+12/-0) doc/en/whats-new/whats-new-in-2.3.txt (+3/-2) |
| To merge this branch: | bzr merge lp:~spiv/bzr/sprout-does-not-reopen-repo |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Vincent Ladeuil | Approve on 2010-12-14 | ||
| John A Meinel | 2010-11-17 | Needs Information on 2010-12-10 | |
|
Review via email:
|
|||
Commit Message
Avoid reopening (and relocking) the same branches/
Description of the Change
This is a step towards bug 309682. It's not quite in a finished state, but I would appreciate feedback.
The idea here is pretty simple: ControlDir.sprout shouldn't open the same repository multiple times. This patch achieves that, and sure enough it causes the worst HPSS ratchet to improve by another notch.
There are a couple of dissatisfying aspects, though:
1. sprout calls branch.sprout after opening the result repository. So this
patch adds a new param (repository/
Branch.
signatures. Perhaps something more radical is called for, like a single
API to acquire or create both a branch and a repo?
2. For some reason, when stacking, the same fallback is added twice, which
confuses _unstack. (Maybe this only happens for RemoteBranches?) I'm
not sure exactly why this happens, but the hack to simply ignore
duplicate _activate_
is an XXX in the patch.
3. It's at least theoretically possible that the repository object we've
already acquired locally doesn't have the same location as the one
suggested by the server (e.g. if the server has a bug, or there's a race
with another client changing something, or perhaps it can even happen
legitimately?). What ought to happen in this case? I suppose this is
already an issue, which the code currently ignores because of the
independent open_repository calls. This is an XXX and AssertionError
in the patch.
Comments on these or any other parts of this patch are very welcome.
- 5540. By Andrew Bennetts on 2010-11-24
-
Merge lp:bzr
- 5541. By Andrew Bennetts on 2010-11-30
-
found_repository test fix from fetch-all-
tags-309682. - 5542. By Andrew Bennetts on 2010-11-30
-
Another small test fix from fetch-all-
tags-309682. - 5543. By Andrew Bennetts on 2010-11-30
-
Better repository URL-mismatch logic in RemoteBranchFor
mat.initialize from fetch-all- tags-309682.
| Vincent Ladeuil (vila) wrote : | # |
I would almost agree with John about the practical aspect (it works, let's land).
On the other hand, you have already spent a good amount of time on this which will be necessary again if we want to provide a cleaner solution.
But...
267 registry,
268 + repository,
269 revision as _mod_revision,
seems weird. I'd like jelmer's feedback here, but I'm pretty sure we pull controldir out of bzrdir to make sure it was isolated from bzr specifics and having to reintroduce repository here sounds like a step backward.
Also,
10 + # This fallback is already configured. This probably only
11 + # happens because BzrDir.sprout is a horrible mess. To avoid
12 + # confusing _unstack we don't add this a second time.
13 + # XXX: log a warning, maybe?
14 + return
is a sign that you're close to nailing the issue and I think you should ;)
On the overall, we have a 'repository' attribute on the branch object, so having to provide it should only occur when we are creating this object. Do we have that many different ways to create branches that you end up modifying so many signatures ? Doesn't it reveal a deeper issue ?
- 5544. By Andrew Bennetts on 2010-12-14
-
Garden the imports in controldir.py.
| Andrew Bennetts (spiv) wrote : | # |
Vincent Ladeuil wrote:
> Review: Needs Information
> I would almost agree with John about the practical aspect (it works, let's land).
>
> On the other hand, you have already spent a good amount of time on this which will be necessary again if we want to provide a cleaner solution.
>
> But...
>
> 267 registry,
> 268 + repository,
> 269 revision as _mod_revision,
>
> seems weird. I'd like jelmer's feedback here, but I'm pretty sure we pull
> controldir out of bzrdir to make sure it was isolated from bzr specifics and
> having to reintroduce repository here sounds like a step backward.
That seems to be a leftover from an earlier version of this patch. It's
not actually used. I've removed that import (and gardened a couple of
others noticed by pyflakes). Thanks for spotting that.
> Also,
>
> 10 + # This fallback is already configured. This probably only
> 11 + # happens because BzrDir.sprout is a horrible mess. To avoid
> 12 + # confusing _unstack we don't add this a second time.
> 13 + # XXX: log a warning, maybe?
> 14 + return
>
> is a sign that you're close to nailing the issue and I think you should ;)
If I thought I was close I'd have nailed it already!
> On the overall, we have a 'repository' attribute on the branch object, so
> having to provide it should only occur when we are creating this object. Do we
> have that many different ways to create branches that you end up modifying so
> many signatures ? Doesn't it reveal a deeper issue ?
I agree, I think there's a deeper issue here, as my cover letter tried
to say. I'm not sure what a good way solution is.
Regarding the number of ways to create branches, here's one way to count
that, based on this diff:
* 8 definitions of BranchFormat.
* 4 definitions of ControlDir.
* 1 definition of Branch.sprout
That doesn't count definitions in test code.
Plus there's open methods, which create branch objects, which are also
affected:
* 3 definitions of BranchFormat.open
So yes, we do have 16 different ways to create a branch object, hence
why I touch so many methods. I don't see an obvious solution to that.
A possible approach might be to have the low-level
BranchFormat.
without the repository object being set, so returning only partially
initialized Branch objects. Then have higher-level APIs (along the
lines of the existing open_containg_
here too?) that assemble these into fully initialized objects with
.repository attributes filled in. There's the related consideration
that parts of the code want to open and/or create some combination of
branch/repo/tree in one logical step (and ideally one network
roundtrip), but the current design opens each of the bzrdir, repository,
and branch separately. I think this is part of the cause of the double
add_fallback ugliness that's an XXX for that matter.
So my suspicion is a fairly fundamental redesign of how we open/create
these things would be help a lot... but getting it right may take some
effort. And it's likely to be way more disruptive to bzr-svn and
friends than a new keyword param! Until someone has a concrete ...
- 5545. By Andrew Bennetts on 2010-12-14
-
Do as the XXX and John's review suggest: log a warning about duplicate fallback activation.
| Jelmer Vernooij (jelmer) wrote : | # |
I've only reviewed this for possible issues with foreign VCS implementations, and it seems fine in that regard (bearing in mind the new repository= parameter).
| Vincent Ladeuil (vila) wrote : | # |
Thanks, Jelmer !
Ok, so my main concerns are addressed, just a few remarks, possibly tweaks:
379 + if not isinstance(
380 + raise AssertionError('xxx %r' % (repository,))
replacing this 'xxx' with something meaningful can only help people confronted with the raised assertion ;)
406 + raise AssertionError(
407 + 'diff %r: %r vs. (%r + %r)' %
408 + (url_diff, repository.
ditto (less sure here, the tb may be enough)
And finally, you summary in your reply above would be nice to keep in devnotes IMHO. Let's not redo this the next time we want to address the deeper issue.
- 5546. By Andrew Bennetts on 2010-12-14
-
Give more helpful message in AssertionErrors, just in case.
- 5547. By Andrew Bennetts on 2010-12-14
-
Merge lp:bzr.
- 5548. By Andrew Bennetts on 2010-12-14
-
Update release-notes and whats-new.
- 5549. By Andrew Bennetts on 2010-12-15
-
Fix a test failure (_TestBranch needs to implement lock_read/unlock).
| Andrew Bennetts (spiv) wrote : | # |
sent to pqm by email

Sorry about the delay on this. In general, I really like the idea of this patch.
I would at least mutter a warning about the double fallback, we don't have to display it on the screen. It would be nice to fix it, but you don't have to get everything right on the first attempt.
I really don't like the proliferation of "no, really, use this object" parameters. I think the problem is that BzrDir.sprout() wants to be the master, but it still defers some of the work to Branch/ Repo/WorkingTre e. I don't have a better answer, though. I know you mentioned this, too.
I'd personally really like to see a: write_locked( create= True)
X.open_
Or something along those lines.
I think part of the confusion is also that if you got something which is a Branch, and you think there is a tree there, the standard use is: bzrdir. open_workingtre e()
branch.
However, that *reopens* the Branch and Repository.
We also have a lot of code that does stuff like:
a) If there is a WT, do X
b) If not, but there is a Branch, do Y
c) If not, but there is a Repository, do Z
It would be nice to simplify a lot of that if we could. That is some of what "BzrDir. open_containing _tree_or_ branch" is supposed to be. Though many times I want "open_containin g_tree_ or_direct_ branch" (don't recurse for a branch, but you can recurse for a Tree).
This is potentially disruptive to bzr-svn, because it adds a new parameter that BzrDir will be passing down the stack. As such, adding a cleaner new api may be an easier way to get what we want. It would let us add a compatability shim for objects that don't implement the new interface, and could be cleaner overall.
Then again, the practical side of me says, you've done the work, it works, even if it isn't perfect, it is better than what we have.