mercurial/subrepo.py
changeset 13086 8db85e39d59c
parent 13085 b4814f1f415c
child 13087 cca0779b4832
equal deleted inserted replaced
13085:b4814f1f415c 13086:8db85e39d59c
   668     def _gitisancestor(self, r1, r2):
   668     def _gitisancestor(self, r1, r2):
   669         base = self._gitcommand(['merge-base', r1, r2])
   669         base = self._gitcommand(['merge-base', r1, r2])
   670         return base == r1
   670         return base == r1
   671 
   671 
   672     def _gitbranchmap(self):
   672     def _gitbranchmap(self):
   673         'returns the current branch and a map from git revision to branch[es]'
   673         '''returns 3 things:
   674         bm = {}
   674         the current branch,
   675         redirects = {}
   675         a map from git branch to revision
       
   676         a map from revision to branches'''
       
   677         branch2rev = {}
       
   678         rev2branch = {}
   676         current = None
   679         current = None
   677         out = self._gitcommand(['branch', '-a', '--no-color',
   680         out = self._gitcommand(['branch', '-a', '--no-color',
   678                                 '--verbose', '--abbrev=40'])
   681                                 '--verbose', '--no-abbrev'])
   679         for line in out.split('\n'):
   682         for line in out.split('\n'):
   680             if line[2:].startswith('(no branch)'):
   683             if line[2:].startswith('(no branch)'):
   681                 continue
   684                 continue
   682             branch, revision = line[2:].split()[:2]
   685             branch, revision = line[2:].split()[:2]
   683             if revision == '->':
   686             if revision == '->':
   684                 continue # ignore remote/HEAD redirects
   687                 continue # ignore remote/HEAD redirects
   685             if line[0] == '*':
   688             if line[0] == '*':
   686                 current = branch
   689                 current = branch
   687             bm.setdefault(revision, []).append(branch)
   690             branch2rev[branch] = revision
   688         return current, bm
   691             rev2branch.setdefault(revision, []).append(branch)
       
   692         return current, branch2rev, rev2branch
   689 
   693 
   690     def _fetch(self, source, revision):
   694     def _fetch(self, source, revision):
   691         if not os.path.exists('%s/.git' % self._path):
   695         if not os.path.exists('%s/.git' % self._path):
   692             self._ui.status(_('cloning subrepo %s\n') % self._relpath)
   696             self._ui.status(_('cloning subrepo %s\n') % self._relpath)
   693             self._gitnodir(['clone', source, self._path])
   697             self._gitnodir(['clone', source, self._path])
   717             if self._gitstate() == revision:
   721             if self._gitstate() == revision:
   718                 self._gitcommand(['reset', '--hard', 'HEAD'])
   722                 self._gitcommand(['reset', '--hard', 'HEAD'])
   719                 return
   723                 return
   720         elif self._gitstate() == revision:
   724         elif self._gitstate() == revision:
   721             return
   725             return
   722         current, bm = self._gitbranchmap()
   726         current, branch2rev, rev2branch = self._gitbranchmap()
   723         if revision not in bm:
   727         if revision not in rev2branch:
   724             # no branch to checkout, check it out with no branch
   728             # no branch to checkout, check it out with no branch
   725             self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
   729             self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
   726                           self._relpath)
   730                           self._relpath)
   727             self._ui.warn(_('check out a git branch if you intend '
   731             self._ui.warn(_('check out a git branch if you intend '
   728                             'to make changes\n'))
   732                             'to make changes\n'))
   729             self._gitcommand(['checkout', '-q', revision])
   733             self._gitcommand(['checkout', '-q', revision])
   730             return
   734             return
   731         branches = bm[revision]
   735         branches = rev2branch[revision]
   732         firstlocalbranch = None
   736         firstlocalbranch = None
   733         for b in branches:
   737         for b in branches:
   734             if b == 'master':
   738             if b == 'master':
   735                 # master trumps all other branches
   739                 # master trumps all other branches
   736                 self._gitcommand(['checkout', 'master'])
   740                 self._gitcommand(['checkout', 'master'])
   766         elif base != self._state[1]:
   770         elif base != self._state[1]:
   767             self._gitcommand(['merge', '--no-commit', revision])
   771             self._gitcommand(['merge', '--no-commit', revision])
   768 
   772 
   769     def push(self, force):
   773     def push(self, force):
   770         # if a branch in origin contains the revision, nothing to do
   774         # if a branch in origin contains the revision, nothing to do
   771         current, bm = self._gitbranchmap()
   775         current, branch2rev, rev2branch = self._gitbranchmap()
   772         for revision, branches in bm.iteritems():
   776         for b, revision in branch2rev.iteritems():
   773             for b in branches:
   777             if b.startswith('remotes/origin'):
   774                 if b.startswith('remotes/origin'):
   778                 if self._gitisancestor(self._state[1], revision):
   775                     if self._gitisancestor(self._state[1], revision):
   779                     return True
   776                         return True
       
   777         # otherwise, try to push the currently checked out branch
   780         # otherwise, try to push the currently checked out branch
   778         cmd = ['push']
   781         cmd = ['push']
   779         if force:
   782         if force:
   780             cmd.append('--force')
   783             cmd.append('--force')
   781         if current:
   784         if current: