comparison mercurial/subrepo.py @ 13086:8db85e39d59c

subrepo: return both mapping directions from gitbranchmap
author Eric Eisner <ede@mit.edu>
date Sun, 28 Nov 2010 15:21:23 -0500
parents b4814f1f415c
children cca0779b4832
comparison
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: