[MERGE] Add Branch support to CommitBuilder

Robert Collins robertc at robertcollins.net
Thu Feb 1 12:45:05 GMT 2007


On Tue, 2007-01-16 at 03:22 +0100, Jelmer Vernooij wrote:
> The attached patch lets CommitBuilder take care of updating the branch
> revision history. It updates the master branch and optionally the local
> branch, if specified.
> 
> This fixes https://bugs.launchpad.net/ubuntu/+source/bzr/+bug/79330
> 
> No backwards compatibility for older versions of CommitBuilder is
> provided. Is that ok, given the number of custom CommitBuilders
> (bzr-svn's is the only I'm aware of), or should there be backwards
> compatibility?

I like the intent [allowing bzr branches bound to svn branches], but I
think the approach is flawed.

Rather than building on the master branch, you should build on the local
branch [which will be a bzr native branch and thus can insert into the
repository without affecting the branch], and then push the revision
into the master branch, and finally update the local branch - as we do.

But what you need, for svn, is for the push to the remote branch to be
talking to the branch, not the repository.

And the problem is that you cant do 'local_branch.push(remote_branch)'

because local_branch has not been updated yet.

One way to allow this is to have the commit builder present a 'virtual'
branch which has the revision appended, without actually putting in the
branch. A trivial decorator would do this.

Another way is to allow a branch to pull a specific revision from a
repository. (or, to allow pushing to a branch from a repository).

looking at my current pull-with-hooks code:

source.lock_read()
try:
    old_count, old_tip = self._last_revision_info(
        self.revision_history())
    try:
        self.update_revisions(source, stop_revision)
    except DivergedBranches:
        if not overwrite:
            raise
    if overwrite:
        self.set_revision_history(source.revision_history())
    new_count, new_tip = self._last_revision_info(
        self.revision_history())
    if _run_hooks:
        if _hook_master:
            _hook_local = self
        else:
            _hook_master = self
            _hook_local = None
        for hook in Branch.hooks['post_pull']:
            hook(source, _hook_local, _hook_master, old_count, old_tip,
                new_count, new_tip)
    return new_count - old_count
finally:
    source.unlock()

The 'source.revision_history()' call is no longer needed - we've had
history canonicalisation for several releases and can move to
history-from-a-single-revid. The update-revisions logic is also somewhat
crufty - in fact we end up setting revision-history twice during
overwrite.

I think theres room for a refactoring here to have update_revisions take
a repository argument, a revision to end up at, and an overwrite flag.
This would then consolidate all the logic from pull, update revisions,
fetch into a rather more focused function (we can give it a new name if
desired). Specifically, fetch would be deprecated, update_revisions will
forward to it, as will pull and commit.

def _NEWMETHOD(self, repository, revision_id, overwrite):
    """Internal Branch method to pull-revisions and set tip revid.

    :param repository: The repository to pull any needed revision
         data from.
    :param revision_id: the revision_id to be set as the last-revision.
    :param overwrite: Whether to set the last revision in the event
        that revision_id is not a child of the current branch tip,
    """"

Thoughts?
-Rob


-- 
GPG key available at: <http://www.robertcollins.net/keys.txt>.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20070201/bc71647a/attachment.pgp 


More information about the bazaar mailing list