def _headssummary(repo, remote, outgoing): """compute a summary of branch and heads status before and after push return {'branch': ([remoteheads], [newheads], [unsyncedheads])} mapping - branch: the branch name - remoteheads: the list of remote heads known locally None if the branch is new - newheads: the new remote heads (known locally) with outgoing pushed - unsyncedheads: the list of remote heads unknown locally. """ cl = repo.changelog headssum = {} # A. Create set of branches involved in the push. branches = set(repo[n].branch() for n in outgoing.missing) remotemap = remote.branchmap() newbranches = branches - set(remotemap) branches.difference_update(newbranches) # A. register remote heads remotebranches = set() for branch, heads in remote.branchmap().iteritems(): remotebranches.add(branch) known = [] unsynced = [] knownnode = cl.hasnode # do not use nodemap until it is filtered for h in heads: if knownnode(h): known.append(h) else: unsynced.append(h) headssum[branch] = (known, list(known), unsynced) # B. add new branch data missingctx = list(repo[n] for n in outgoing.missing) touchedbranches = set() for ctx in missingctx: branch = ctx.branch() touchedbranches.add(branch) if branch not in headssum: headssum[branch] = (None, [], []) # C drop data about untouched branches: for branch in remotebranches - touchedbranches: del headssum[branch] # D. Update newmap with outgoing changes. # This will possibly add new heads and remove existing ones. newmap = branchmap.branchcache((branch, heads[1]) for branch, heads in headssum.iteritems() if heads[0] is not None) newmap.update(repo, (ctx.rev() for ctx in missingctx)) for branch, newheads in newmap.iteritems(): headssum[branch][1][:] = newheads return headssum