Bound branch implementation
John A Meinel
john at arbash-meinel.com
Tue Nov 15 05:39:52 GMT 2005
Robert Collins wrote:
> On Sat, 2005-11-12 at 20:50 -0600, John A Meinel wrote:
>> One use case that comes up fairly often is wanting to have a public
>> location where people can download your branches, while still having a
>> local branch that you can use offline.
>> Also, frequently people want to have some sort of centralized
>> development, where they have a shared branch that multiple people can
>> commit to. In this sort of mode, you have to update your local tree
>> before you can commit.
>>
>> So, I think I have an implementation which works. It is built off of
>> Robert's integration branch, and is available from here:
>> http://bzr.arbash-meinel.com/branches/bzr/bound-branch/
>>
>> Eventually, we want to put this into bzr core, but first I would like to
>> get some feedback. I made sure committing when bound has a decent error
>> message, but I'm not sure that I've tracked down all the other
>> possibilities.
>>
>> My test cases work, indicating the functionality is there, but that
>> doesn't mean the user interface is perfect. Also, I believe it will fail
>> when bound to a remote tree, since we can't update remote WorkingTrees.
>> I don't know if we will support updating remote trees, or just creating
>> branches without remote working trees.
>
> Heres some code level feedback ...
>
> ...
> # TODO: Should unbinding a non-bound branch fail?
> + #bzr('unbind')
>
>
> I think unbinding an unbound branch is an error.
>
I think right now it is an error (because the delete raises an
exception, though LocalTransport is (slightly) borked because it should
raise NoSuchFile, and instead it is letting the IOError be generically
trapped into a LocalTransportError)
>
> I think it would be nice to have all tests that call self.run_bzr in
> selftest/blackbox.py - or perhaps we should make a blackbox package ?
> (It means there is a predictable place to go to find ui level tests.)
I would be okay with a blackbox package, but I generally don't prefer to
have everything in one file.
>
> hooking into set_revision_history seems very wrong to me. Firstly, we
> may be nuking the concept completely. Secondly, I think its less clear ,
> and more prone to confusion, than if we just do operations like commit
> to the bound-to branch first. I.e. commit commits the local working dir
> to the remote branch, then adds the same revision to the local branch,
> and finally sets the local revision history.
Actually, I think performance-wise, having commit do all of the work
locally, which can then be simply pulled up to the remote is just as
clean. Especially with knits.
I doubt we will get rid of set_revision_history, but I could be wrong.
Certainly we could have commit do the operation.
>
> Likewise pull --overwrite would affect the bound-to branch first, then
> the local one. If interrupted both of these operations will simply need
> a 'bzr update' or similar - at worst a update --overwrite - to reconcile
> the branches.
>
> in missing_revisions and update_revisions, why do you need to pass in an
> other_history ? Is it an optimisation ?
The local revision history hasn't actually been modified yet, but I know
what it wants to become. I can just pass in the revision_id (if I hack
around a different check, which wants the revision_id to exist in the
local revision_history), which causes it to use the
"get_intervening_revisions" codepath.
The biggest thing is that it was giving me a nicer exception
(DivergedBranches), rather than giving me (NoSuchRevision).
>
> get_bound_location should be @needs_read_lock. In general anything that
> reads will need @needs_read_lock, and anything that writes
> @needs_write_lock. Using these will cause caching to occur
> automatically, where appropriate.
No problem.
>
> It might be nice to have a 'BoundBranch' branch class which incorporates
> the bound behaviour. This would be returned as appropriate from
> Branch.open/open_containing. I can clean up the code around there if
> needed to make this easier. Alternatively, one could adapt a branch to
> be a BoundBranch, though I don't know if thats feasible at the moment.
But you just finished saying that it needs to be done at the commit and
pull level, which are way above the actual Branch object. Commit is an
entire semi-complex class in itself, pull is certainly implemented
internally in the branch.
I think commit could go out and check that it is up-to-date at the
beginning rather than at the end, but really it should do all of the
weave updates and any other stuff on the local files, not on the remote
branch. And then upload the changes when it has worked everything out.
Why download the remote files, when you should have everything you need
locally. If you wanted to be pedantic, I suppose you could download
just the table of contents (this is much easier with knits), and make
sure you have the same contents.
>
> In either case, a normal branch could have bind() on it, and BoundBranch
> unbind(). :)
Except then you need to use "hasattr()" to detect which one you have,
rather than catching the "branch is not bound" exception. If you *don't*
use hasattr, then you get the AttributeError exception, which I think is
bogus.
>
> I like the way its shaping up though, now for soft-failures!
At the level I did it, it isn't that hard to implement soft-failures.
Just at the point where I do "Branch.open(bound_loc)" you can decide
what to do if you aren't able to connect to the other branch. Of course,
whatever the mechanism we end up with, that is the same process.
>
> Rob
>
John
=:->
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 249 bytes
Desc: OpenPGP digital signature
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20051114/152f58c3/attachment.pgp
More information about the bazaar
mailing list