Mercurial > hg
comparison mercurial/localrepo.py @ 11211:e43c23d189a5
push: add --new-branch option to allow intial push of new branches
Compare this to --force which allows anything to be pushed. With --new-branch,
only changesets to named branches not present on the and changesets not
introducing additional heads on existing branches are allowed.
Developed by
Henrik Stuart <henrik.stuart@edlund.dk>
Sune Foldager <cryo@cyanite.org>
author | Sune Foldager <cryo@cyanite.org> |
---|---|
date | Fri, 21 May 2010 15:22:29 +0200 |
parents | 6a64813276ed |
children | 5cdac5c35e68 |
comparison
equal
deleted
inserted
replaced
11210:0c0088881562 | 11211:e43c23d189a5 |
---|---|
1505 cg = remote.changegroupsubset(fetch, heads, 'pull') | 1505 cg = remote.changegroupsubset(fetch, heads, 'pull') |
1506 return self.addchangegroup(cg, 'pull', remote.url()) | 1506 return self.addchangegroup(cg, 'pull', remote.url()) |
1507 finally: | 1507 finally: |
1508 lock.release() | 1508 lock.release() |
1509 | 1509 |
1510 def push(self, remote, force=False, revs=None): | 1510 def push(self, remote, force=False, revs=None, newbranch=False): |
1511 '''Push outgoing changesets (limited by revs) from the current | 1511 '''Push outgoing changesets (limited by revs) from the current |
1512 repository to remote. Return an integer: | 1512 repository to remote. Return an integer: |
1513 - 0 means HTTP error *or* nothing to push | 1513 - 0 means HTTP error *or* nothing to push |
1514 - 1 means we pushed and remote head count is unchanged *or* | 1514 - 1 means we pushed and remote head count is unchanged *or* |
1515 we have outgoing changesets but refused to push | 1515 we have outgoing changesets but refused to push |
1522 # | 1522 # |
1523 # unbundle assumes local user cannot lock remote repo (new ssh | 1523 # unbundle assumes local user cannot lock remote repo (new ssh |
1524 # servers, http servers). | 1524 # servers, http servers). |
1525 | 1525 |
1526 if remote.capable('unbundle'): | 1526 if remote.capable('unbundle'): |
1527 return self.push_unbundle(remote, force, revs) | 1527 return self.push_unbundle(remote, force, revs, newbranch) |
1528 return self.push_addchangegroup(remote, force, revs) | 1528 return self.push_addchangegroup(remote, force, revs, newbranch) |
1529 | 1529 |
1530 def prepush(self, remote, force, revs): | 1530 def prepush(self, remote, force, revs, newbranch): |
1531 '''Analyze the local and remote repositories and determine which | 1531 '''Analyze the local and remote repositories and determine which |
1532 changesets need to be pushed to the remote. Return value depends | 1532 changesets need to be pushed to the remote. Return value depends |
1533 on circumstances: | 1533 on circumstances: |
1534 | 1534 |
1535 If we are not going to push anything, return a tuple (None, | 1535 If we are not going to push anything, return a tuple (None, |
1584 branches = set(self[n].branch() for n in outg) | 1584 branches = set(self[n].branch() for n in outg) |
1585 | 1585 |
1586 # 2. Check for new branches on the remote. | 1586 # 2. Check for new branches on the remote. |
1587 remotemap = remote.branchmap() | 1587 remotemap = remote.branchmap() |
1588 newbranches = branches - set(remotemap) | 1588 newbranches = branches - set(remotemap) |
1589 if newbranches: # new branch requires --force | 1589 if newbranches and not newbranch: # new branch requires --new-branch |
1590 branchnames = ', '.join("%s" % b for b in newbranches) | 1590 branchnames = ', '.join("%s" % b for b in newbranches) |
1591 self.ui.warn(_("abort: push creates " | 1591 self.ui.warn(_("abort: push creates " |
1592 "new remote branches: %s!\n") | 1592 "new remote branches: %s!\n") |
1593 % branchnames) | 1593 % branchnames) |
1594 self.ui.status(_("(use 'hg push -f' to force)\n")) | 1594 self.ui.status(_("(use 'hg push --new-branch' to create new " |
1595 "remote branches)\n")) | |
1595 return None, 0 | 1596 return None, 0 |
1597 branches.difference_update(newbranches) | |
1596 | 1598 |
1597 # 3. Construct the initial oldmap and newmap dicts. | 1599 # 3. Construct the initial oldmap and newmap dicts. |
1598 # They contain information about the remote heads before and | 1600 # They contain information about the remote heads before and |
1599 # after the push, respectively. | 1601 # after the push, respectively. |
1600 # Heads not found locally are not included in either dict, | 1602 # Heads not found locally are not included in either dict, |
1652 cg = self._changegroup(nodes, 'push') | 1654 cg = self._changegroup(nodes, 'push') |
1653 else: | 1655 else: |
1654 cg = self.changegroupsubset(update, revs, 'push') | 1656 cg = self.changegroupsubset(update, revs, 'push') |
1655 return cg, remote_heads | 1657 return cg, remote_heads |
1656 | 1658 |
1657 def push_addchangegroup(self, remote, force, revs): | 1659 def push_addchangegroup(self, remote, force, revs, newbranch): |
1658 '''Push a changegroup by locking the remote and sending the | 1660 '''Push a changegroup by locking the remote and sending the |
1659 addchangegroup command to it. Used for local and old SSH repos. | 1661 addchangegroup command to it. Used for local and old SSH repos. |
1660 Return an integer: see push(). | 1662 Return an integer: see push(). |
1661 ''' | 1663 ''' |
1662 lock = remote.lock() | 1664 lock = remote.lock() |
1663 try: | 1665 try: |
1664 ret = self.prepush(remote, force, revs) | 1666 ret = self.prepush(remote, force, revs, newbranch) |
1665 if ret[0] is not None: | 1667 if ret[0] is not None: |
1666 cg, remote_heads = ret | 1668 cg, remote_heads = ret |
1667 # here, we return an integer indicating remote head count change | 1669 # here, we return an integer indicating remote head count change |
1668 return remote.addchangegroup(cg, 'push', self.url()) | 1670 return remote.addchangegroup(cg, 'push', self.url()) |
1669 # and here we return 0 for "nothing to push" or 1 for | 1671 # and here we return 0 for "nothing to push" or 1 for |
1670 # "something to push but I refuse" | 1672 # "something to push but I refuse" |
1671 return ret[1] | 1673 return ret[1] |
1672 finally: | 1674 finally: |
1673 lock.release() | 1675 lock.release() |
1674 | 1676 |
1675 def push_unbundle(self, remote, force, revs): | 1677 def push_unbundle(self, remote, force, revs, newbranch): |
1676 '''Push a changegroup by unbundling it on the remote. Used for new | 1678 '''Push a changegroup by unbundling it on the remote. Used for new |
1677 SSH and HTTP repos. Return an integer: see push().''' | 1679 SSH and HTTP repos. Return an integer: see push().''' |
1678 # local repo finds heads on server, finds out what revs it | 1680 # local repo finds heads on server, finds out what revs it |
1679 # must push. once revs transferred, if server finds it has | 1681 # must push. once revs transferred, if server finds it has |
1680 # different heads (someone else won commit/push race), server | 1682 # different heads (someone else won commit/push race), server |
1681 # aborts. | 1683 # aborts. |
1682 | 1684 |
1683 ret = self.prepush(remote, force, revs) | 1685 ret = self.prepush(remote, force, revs, newbranch) |
1684 if ret[0] is not None: | 1686 if ret[0] is not None: |
1685 cg, remote_heads = ret | 1687 cg, remote_heads = ret |
1686 if force: | 1688 if force: |
1687 remote_heads = ['force'] | 1689 remote_heads = ['force'] |
1688 # ssh: return remote's addchangegroup() | 1690 # ssh: return remote's addchangegroup() |