mercurial/subrepo.py
changeset 13087 cca0779b4832
parent 13086 8db85e39d59c
child 13093 d0cbddfe3f4c
equal deleted inserted replaced
13086:8db85e39d59c 13087:cca0779b4832
   689                 current = branch
   689                 current = branch
   690             branch2rev[branch] = revision
   690             branch2rev[branch] = revision
   691             rev2branch.setdefault(revision, []).append(branch)
   691             rev2branch.setdefault(revision, []).append(branch)
   692         return current, branch2rev, rev2branch
   692         return current, branch2rev, rev2branch
   693 
   693 
       
   694     def _gittracking(self, branches):
       
   695         'return map of remote branch to local tracking branch'
       
   696         # assumes no more than one local tracking branch for each remote
       
   697         tracking = {}
       
   698         for b in branches:
       
   699             if b.startswith('remotes/'):
       
   700                 continue
       
   701             remote = self._gitcommand(['config', 'branch.%s.remote' % b])
       
   702             if remote:
       
   703                 ref = self._gitcommand(['config', 'branch.%s.merge' % b])
       
   704                 tracking['remotes/%s/%s' % (remote, ref.split('/')[-1])] = b
       
   705         return tracking
       
   706 
   694     def _fetch(self, source, revision):
   707     def _fetch(self, source, revision):
   695         if not os.path.exists('%s/.git' % self._path):
   708         if not os.path.exists('%s/.git' % self._path):
   696             self._ui.status(_('cloning subrepo %s\n') % self._relpath)
   709             self._ui.status(_('cloning subrepo %s\n') % self._relpath)
   697             self._gitnodir(['clone', source, self._path])
   710             self._gitnodir(['clone', source, self._path])
   698         if self._githavelocally(revision):
   711         if self._githavelocally(revision):
   722                 self._gitcommand(['reset', '--hard', 'HEAD'])
   735                 self._gitcommand(['reset', '--hard', 'HEAD'])
   723                 return
   736                 return
   724         elif self._gitstate() == revision:
   737         elif self._gitstate() == revision:
   725             return
   738             return
   726         current, branch2rev, rev2branch = self._gitbranchmap()
   739         current, branch2rev, rev2branch = self._gitbranchmap()
   727         if revision not in rev2branch:
   740 
       
   741         def rawcheckout():
   728             # no branch to checkout, check it out with no branch
   742             # no branch to checkout, check it out with no branch
   729             self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
   743             self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
   730                           self._relpath)
   744                           self._relpath)
   731             self._ui.warn(_('check out a git branch if you intend '
   745             self._ui.warn(_('check out a git branch if you intend '
   732                             'to make changes\n'))
   746                             'to make changes\n'))
   733             self._gitcommand(['checkout', '-q', revision])
   747             self._gitcommand(['checkout', '-q', revision])
       
   748 
       
   749         if revision not in rev2branch:
       
   750             rawcheckout()
   734             return
   751             return
   735         branches = rev2branch[revision]
   752         branches = rev2branch[revision]
   736         firstlocalbranch = None
   753         firstlocalbranch = None
   737         for b in branches:
   754         for b in branches:
   738             if b == 'master':
   755             if b == 'master':
   741                 return
   758                 return
   742             if not firstlocalbranch and not b.startswith('remotes/'):
   759             if not firstlocalbranch and not b.startswith('remotes/'):
   743                 firstlocalbranch = b
   760                 firstlocalbranch = b
   744         if firstlocalbranch:
   761         if firstlocalbranch:
   745             self._gitcommand(['checkout', firstlocalbranch])
   762             self._gitcommand(['checkout', firstlocalbranch])
   746         else:
   763             return
   747             remote = branches[0]
   764 
       
   765         tracking = self._gittracking(branch2rev.keys())
       
   766         # choose a remote branch already tracked if possible
       
   767         remote = branches[0]
       
   768         if remote not in tracking:
       
   769             for b in branches:
       
   770                 if b in tracking:
       
   771                     remote = b
       
   772                     break
       
   773 
       
   774         if remote not in tracking:
       
   775             # create a new local tracking branch
   748             local = remote.split('/')[-1]
   776             local = remote.split('/')[-1]
   749             self._gitcommand(['checkout', '-b', local, remote])
   777             self._gitcommand(['checkout', '-b', local, remote])
       
   778         elif self._gitisancestor(branch2rev[tracking[remote]], remote):
       
   779             # When updating to a tracked remote branch,
       
   780             # if the local tracking branch is downstream of it,
       
   781             # a normal `git pull` would have performed a "fast-forward merge"
       
   782             # which is equivalent to updating the local branch to the remote.
       
   783             # Since we are only looking at branching at update, we need to
       
   784             # detect this situation and perform this action lazily.
       
   785             if tracking[remote] != current:
       
   786                 self._gitcommand(['checkout', tracking[remote]])
       
   787             self._gitcommand(['merge', '--ff', remote])
       
   788         else:
       
   789             # a real merge would be required, just checkout the revision
       
   790             rawcheckout()
   750 
   791 
   751     def commit(self, text, user, date):
   792     def commit(self, text, user, date):
   752         cmd = ['commit', '-a', '-m', text]
   793         cmd = ['commit', '-a', '-m', text]
   753         if user:
   794         if user:
   754             cmd += ['--author', user]
   795             cmd += ['--author', user]