diff -r f8ff65a83169 -r 6b9ec23b09fc mercurial/localrepo.py --- a/mercurial/localrepo.py Sat May 23 17:03:51 2009 +0200 +++ b/mercurial/localrepo.py Sat May 23 17:04:31 2009 +0200 @@ -1429,42 +1429,97 @@ else: bases, heads = update, self.changelog.heads() + def checkbranch(lheads, rheads, updatelh): + ''' + check whether there are more local heads than remote heads on + a specific branch. + + lheads: local branch heads + rheads: remote branch heads + updatelh: outgoing local branch heads + ''' + + warn = 0 + + if not revs and len(lheads) > len(rheads): + warn = 1 + else: + updatelheads = [self.changelog.heads(x, lheads) + for x in updatelh] + newheads = set(sum(updatelheads, [])) & set(lheads) + + 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 not bases: self.ui.status(_("no changes found\n")) return None, 1 elif not force: - # check if we're creating new remote heads - # to be a remote head after push, node must be either + # Check for each named branch if we're creating new remote heads. + # To be a remote head after push, node must be either: # - unknown locally # - a local outgoing head descended from update # - a remote head that's known locally and not # ancestral to an outgoing head + # + # New named branches cannot be created without --force. - warn = 0 + if remote_heads != [nullid]: + if remote.capable('branchmap'): + localhds = {} + if not revs: + localhds = self.branchmap() + else: + for n in heads: + branch = self[n].branch() + if branch in localhds: + localhds[branch].append(n) + else: + localhds[branch] = [n] + + remotehds = remote.branchmap() - if remote_heads == [nullid]: - warn = 0 - elif not revs and len(heads) > len(remote_heads): - warn = 1 - else: - newheads = list(heads) - for r in remote_heads: - 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.append(r) - else: - newheads.append(r) - if len(newheads) > len(remote_heads): - warn = 1 + for lh in localhds: + if lh in remotehds: + rheads = remotehds[lh] + else: + rheads = [] + lheads = localhds[lh] + updatelh = [upd for upd in update + if self[upd].branch() == lh] + if not updatelh: + continue + if not checkbranch(lheads, rheads, updatelh): + return None, 0 + else: + if not checkbranch(heads, remote_heads, update): + return None, 0 - if warn: - 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 None, 0 - elif inc: + if inc: self.ui.warn(_("note: unsynced remote changes!\n"))