318 |
318 |
319 def _branchtags(self, partial, lrev): |
319 def _branchtags(self, partial, lrev): |
320 # TODO: rename this function? |
320 # TODO: rename this function? |
321 tiprev = len(self) - 1 |
321 tiprev = len(self) - 1 |
322 if lrev != tiprev: |
322 if lrev != tiprev: |
323 self._updatebranchcache(partial, lrev + 1, tiprev + 1) |
323 ctxgen = (self[r] for r in xrange(lrev + 1, tiprev + 1)) |
|
324 self._updatebranchcache(partial, ctxgen) |
324 self._writebranchcache(partial, self.changelog.tip(), tiprev) |
325 self._writebranchcache(partial, self.changelog.tip(), tiprev) |
325 |
326 |
326 return partial |
327 return partial |
327 |
328 |
328 def branchmap(self): |
329 def branchmap(self): |
396 f.write("%s %s\n" % (hex(node), label)) |
397 f.write("%s %s\n" % (hex(node), label)) |
397 f.rename() |
398 f.rename() |
398 except (IOError, OSError): |
399 except (IOError, OSError): |
399 pass |
400 pass |
400 |
401 |
401 def _updatebranchcache(self, partial, start, end): |
402 def _updatebranchcache(self, partial, ctxgen): |
402 # collect new branch entries |
403 # collect new branch entries |
403 newbranches = {} |
404 newbranches = {} |
404 for r in xrange(start, end): |
405 for c in ctxgen: |
405 c = self[r] |
|
406 newbranches.setdefault(c.branch(), []).append(c.node()) |
406 newbranches.setdefault(c.branch(), []).append(c.node()) |
407 # if older branchheads are reachable from new ones, they aren't |
407 # if older branchheads are reachable from new ones, they aren't |
408 # really branchheads. Note checking parents is insufficient: |
408 # really branchheads. Note checking parents is insufficient: |
409 # 1 (branch a) -> 2 (branch b) -> 3 (branch a) |
409 # 1 (branch a) -> 2 (branch b) -> 3 (branch a) |
410 for branch, newnodes in newbranches.iteritems(): |
410 for branch, newnodes in newbranches.iteritems(): |
1501 inc = self.findincoming(remote, common, remote_heads, force=force) |
1501 inc = self.findincoming(remote, common, remote_heads, force=force) |
1502 |
1502 |
1503 update, updated_heads = self.findoutgoing(remote, common, remote_heads) |
1503 update, updated_heads = self.findoutgoing(remote, common, remote_heads) |
1504 msng_cl, bases, heads = self.changelog.nodesbetween(update, revs) |
1504 msng_cl, bases, heads = self.changelog.nodesbetween(update, revs) |
1505 |
1505 |
1506 def checkbranch(lheads, rheads, updatelb, branchname=None): |
1506 def checkbranch(lheads, rheads, branchname=None): |
1507 ''' |
1507 ''' |
1508 check whether there are more local heads than remote heads on |
1508 check whether there are more local heads than remote heads on |
1509 a specific branch. |
1509 a specific branch. |
1510 |
1510 |
1511 lheads: local branch heads |
1511 lheads: local branch heads |
1512 rheads: remote branch heads |
1512 rheads: remote branch heads |
1513 updatelb: outgoing local branch bases |
|
1514 ''' |
1513 ''' |
1515 |
1514 |
1516 warn = 0 |
1515 warn = 0 |
1517 |
1516 |
1518 if not revs and len(lheads) > len(rheads): |
1517 if len(lheads) > len(rheads): |
1519 warn = 1 |
1518 warn = 1 |
1520 else: |
1519 else: |
1521 # add local heads involved in the push |
|
1522 updatelheads = [self.changelog.heads(x, lheads) |
|
1523 for x in updatelb] |
|
1524 newheads = set(sum(updatelheads, [])) & set(lheads) |
|
1525 |
|
1526 if not newheads: |
|
1527 return True |
|
1528 |
|
1529 # add heads we don't have or that are not involved in the push |
1520 # add heads we don't have or that are not involved in the push |
|
1521 newheads = set(lheads) |
1530 for r in rheads: |
1522 for r in rheads: |
1531 if r in self.changelog.nodemap: |
1523 if r in self.changelog.nodemap: |
1532 desc = self.changelog.heads(r, heads) |
1524 desc = self.changelog.heads(r, heads) |
1533 l = [h for h in heads if h in desc] |
1525 l = [h for h in heads if h in desc] |
1534 if not l: |
1526 if not l: |
1573 |
1565 |
1574 if not revs: |
1566 if not revs: |
1575 localbrheads = self.branchmap() |
1567 localbrheads = self.branchmap() |
1576 else: |
1568 else: |
1577 localbrheads = {} |
1569 localbrheads = {} |
1578 for n in heads: |
1570 ctxgen = (self[n] for n in msng_cl) |
1579 branch = self[n].branch() |
1571 self._updatebranchcache(localbrheads, ctxgen) |
1580 localbrheads.setdefault(branch, []).append(n) |
|
1581 |
1572 |
1582 newbranches = list(set(localbrheads) - set(remotebrheads)) |
1573 newbranches = list(set(localbrheads) - set(remotebrheads)) |
1583 if newbranches: # new branch requires --force |
1574 if newbranches: # new branch requires --force |
1584 branchnames = ', '.join("%s" % b for b in newbranches) |
1575 branchnames = ', '.join("%s" % b for b in newbranches) |
1585 self.ui.warn(_("abort: push creates " |
1576 self.ui.warn(_("abort: push creates " |
1589 self.ui.status(_("(use 'hg push -f' to force)\n")) |
1580 self.ui.status(_("(use 'hg push -f' to force)\n")) |
1590 return None, 0 |
1581 return None, 0 |
1591 for branch, lheads in localbrheads.iteritems(): |
1582 for branch, lheads in localbrheads.iteritems(): |
1592 if branch in remotebrheads: |
1583 if branch in remotebrheads: |
1593 rheads = remotebrheads[branch] |
1584 rheads = remotebrheads[branch] |
1594 if not checkbranch(lheads, rheads, update, branch): |
1585 if not checkbranch(lheads, rheads, branch): |
1595 return None, 0 |
1586 return None, 0 |
1596 else: |
1587 else: |
1597 if not checkbranch(heads, remote_heads, update): |
1588 if not checkbranch(heads, remote_heads): |
1598 return None, 0 |
1589 return None, 0 |
1599 |
1590 |
1600 if inc: |
1591 if inc: |
1601 self.ui.warn(_("note: unsynced remote changes!\n")) |
1592 self.ui.warn(_("note: unsynced remote changes!\n")) |
1602 |
1593 |