[PATCH 1 of 1] Handle prepush logic for named branches

Henrik Stuart henrik.stuart at edlund.dk
Fri May 22 07:54:56 CDT 2009


Matt Mackall wrote:
> On Tue, May 19, 2009 at 08:31:10AM +0200, Henrik Stuart wrote:
>> # HG changeset patch
>> # User Sune Foldager <cryo at cyanite.org>
>> # Date 1241528982 -7200
>> # Node ID 94ac3cbde1772b46ed4b86bfe140b42b73d4b784
>> # Parent  252232621165917755727729c7f0b9a1f1263668
>> Handle prepush logic for named branches

[snip]

>> diff -r 252232621165 -r 94ac3cbde177 mercurial/hgweb/protocol.py
>> --- a/mercurial/hgweb/protocol.py	Tue May 19 01:37:38 2009 +0200
>> +++ b/mercurial/hgweb/protocol.py	Tue May 05 15:09:42 2009 +0200
>> @@ -17,6 +17,7 @@
>>  __all__ = [
>>     'lookup', 'heads', 'branches', 'between', 'changegroup',
>>     'changegroupsubset', 'capabilities', 'unbundle', 'stream_out',
>> +   'branchmap',
>>  ]
>>  
>>  HGTYPE = 'application/mercurial-0.1'
>> @@ -37,6 +38,12 @@
>>      req.respond(HTTP_OK, HGTYPE, length=len(resp))
>>      yield resp
>>  
>> +def branchmap(repo, req):
>> +    branches = repo.branchmap()
>> +    resp = "\n".join(['%s %s' % (b, " ".join([hex(x) for x in branches[b]])) for b in branches])
>> +    req.respond(HTTP_OK, HGTYPE, length=len(resp))
>> +    yield resp
>> +
> 
> Hmm. Can we name this branchheads instead for better parallelism with
> heads? Or does that too strongly suggest only heads of one branch?

branchheads is already used for a heads from a single branch. branchmap
should illustrate the correct behaviour adequately, in my opinion.

> Looks like there's nothing currently branches from containing nasty
> things like spaces or newlines. Hmm.

This should probably be addressed in a patch different to these patches.

>> +                        if not newheads:
>> +                            return True
>> +
>> +                        for r in rheads:
>> +                            if r in self.changelog.nodemap:
>> +                                desc = self.changelog.heads(r, heads)
>> +                                l = [h for h in heads if h in desc]
>> +                                if not l:
>> +                                    newheads.add(r)
>> +                            else:
>> +                                newheads.add(r)
>> +                        if len(newheads) > len(rheads):
>> +                            warn = 1
>> +
>> +                    if warn:
>> +                        if not rheads: # new branch requires --force
>> +                            self.ui.warn(_("abort: push creates new remote branch '%s'!\n" % self[updatelh[0]].branch()))
>> +                        else:
>> +                            self.ui.warn(_("abort: push creates new remote heads!\n"))
>> +
>> +                        self.ui.status(_("(did you forget to merge?"
>> +                                     " use push -f to force)\n"))
>> +                        return False
>> +                    return True
>> +
>> +                if remote.capable('branchmap'):
>> +                    local_hds = {}
>> +                    if not revs:
>> +                        local_hds = self.branchmap()
>> +                    else:
>> +                        for n in heads:
>> +                            branch = self[n].branch()
>> +                            if local_hds.has_key(branch):
>> +                                local_hds[branch].append(n)
>> +                            else:
>> +                                local_hds[branch] = [n]
>> +
>> +                    remote_hds = remote.branchmap()
>> +
>> +                    for lh in local_hds:
>> +                        rheads = remote_hds[lh] if remote_hds.has_key(lh) else []
>> +                        lheads = local_hds[lh]
>> +                        updatelh = [upd for upd in update if self[upd].branch() == lh]
>> +                        if not updatelh:
>> +                            continue
>> +                        if not creates_no_new_heads(lheads, rheads, updatelh):
>> +                            return None, 0
>> +                else:
>> +                    if not creates_no_new_heads(heads, remote_heads, update):
>> +                        return None, 0
> 
> I think we could probably arrange for there to be only one call to the
> heads function? Doesn't look like heads/remote_heads/update gets used
> after this point.

I'm not following... in one instance it's called inside a loop, in the
other, it is not. I don't see how you'd want to refactor that into a
single call.

>> diff -r 252232621165 -r 94ac3cbde177 tests/test-acl.out
>> --- a/tests/test-acl.out	Tue May 19 01:37:38 2009 +0200
>> +++ b/tests/test-acl.out	Tue May 05 15:09:42 2009 +0200
>> @@ -42,6 +42,7 @@
>>  pushing to ../b
>>  searching for changes
>>  common changesets up to 6675d58eff77
>> +invalidating branch cache (tip differs)
> 
> Why are these appearing? Simply because we're checking the branches now?

Because some tests run with --debug and _branchheads tells us it's
invalidating the branch cache in that case. So yes.

-- 
Kind regards,
  Henrik Stuart


More information about the Mercurial-devel mailing list