comparison mercurial/subrepo.py @ 13151:519ac79d680b

subrepo: incorporate tracking branches into gitbranchmap
author Eric Eisner <ede@mit.edu>
date Tue, 14 Dec 2010 21:56:43 -0500
parents 8617b8b74fae
children 70d80907e4b8
comparison
equal deleted inserted replaced
13150:8617b8b74fae 13151:519ac79d680b
673 the current branch, 673 the current branch,
674 a map from git branch to revision 674 a map from git branch to revision
675 a map from revision to branches''' 675 a map from revision to branches'''
676 branch2rev = {} 676 branch2rev = {}
677 rev2branch = {} 677 rev2branch = {}
678 tracking = {}
678 current, err = self._gitdir(['symbolic-ref', 'HEAD', '--quiet']) 679 current, err = self._gitdir(['symbolic-ref', 'HEAD', '--quiet'])
679 if err: 680 if err:
680 current = None 681 current = None
681 682
682 out = self._gitcommand(['for-each-ref', '--format', 683 out = self._gitcommand(['for-each-ref', '--format',
683 '%(objectname) %(refname)']) 684 '%(objectname) %(refname) %(upstream) end'])
684 for line in out.split('\n'): 685 for line in out.split('\n'):
685 revision, ref = line.split(' ') 686 revision, ref, upstream = line.split(' ')[:3]
686 if ref.startswith('refs/tags/'): 687 if ref.startswith('refs/tags/'):
687 continue 688 continue
688 if ref.startswith('refs/remotes/') and ref.endswith('/HEAD'): 689 if ref.startswith('refs/remotes/') and ref.endswith('/HEAD'):
689 continue # ignore remote/HEAD redirects 690 continue # ignore remote/HEAD redirects
690 branch2rev[ref] = revision 691 branch2rev[ref] = revision
691 rev2branch.setdefault(revision, []).append(ref) 692 rev2branch.setdefault(revision, []).append(ref)
692 return current, branch2rev, rev2branch 693 if upstream:
693 694 # assumes no more than one local tracking branch for a remote
694 def _gittracking(self, branches): 695 tracking[upstream] = ref
695 'return map of remote branch to local tracking branch' 696 return current, branch2rev, rev2branch, tracking
696 # assumes no more than one local tracking branch for each remote
697 tracking = {}
698 for b in branches:
699 if b.startswith('refs/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['refs/remotes/%s/%s' %
705 (remote, ref.split('/', 2)[2])] = b
706 return tracking
707 697
708 def _fetch(self, source, revision): 698 def _fetch(self, source, revision):
709 if not os.path.exists('%s/.git' % self._path): 699 if not os.path.exists('%s/.git' % self._path):
710 self._ui.status(_('cloning subrepo %s\n') % self._relpath) 700 self._ui.status(_('cloning subrepo %s\n') % self._relpath)
711 self._gitnodir(['clone', source, self._path]) 701 self._gitnodir(['clone', source, self._path])
739 if self._gitstate() == revision: 729 if self._gitstate() == revision:
740 self._gitcommand(['reset', '--hard', 'HEAD']) 730 self._gitcommand(['reset', '--hard', 'HEAD'])
741 return 731 return
742 elif self._gitstate() == revision: 732 elif self._gitstate() == revision:
743 return 733 return
744 current, branch2rev, rev2branch = self._gitbranchmap() 734 current, branch2rev, rev2branch, tracking = self._gitbranchmap()
745 735
746 def rawcheckout(): 736 def rawcheckout():
747 # no branch to checkout, check it out with no branch 737 # no branch to checkout, check it out with no branch
748 self._ui.warn(_('checking out detached HEAD in subrepo %s\n') % 738 self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
749 self._relpath) 739 self._relpath)
765 firstlocalbranch = b 755 firstlocalbranch = b
766 if firstlocalbranch: 756 if firstlocalbranch:
767 self._gitcommand(['checkout', firstlocalbranch]) 757 self._gitcommand(['checkout', firstlocalbranch])
768 return 758 return
769 759
770 tracking = self._gittracking(branch2rev.keys())
771 # choose a remote branch already tracked if possible 760 # choose a remote branch already tracked if possible
772 remote = branches[0] 761 remote = branches[0]
773 if remote not in tracking: 762 if remote not in tracking:
774 for b in branches: 763 for b in branches:
775 if b in tracking: 764 if b in tracking:
818 elif base != self._state[1]: 807 elif base != self._state[1]:
819 self._gitcommand(['merge', '--no-commit', revision]) 808 self._gitcommand(['merge', '--no-commit', revision])
820 809
821 def push(self, force): 810 def push(self, force):
822 # if a branch in origin contains the revision, nothing to do 811 # if a branch in origin contains the revision, nothing to do
823 current, branch2rev, rev2branch = self._gitbranchmap() 812 current, branch2rev, rev2branch, tracking = self._gitbranchmap()
824 if self._state[1] in rev2branch: 813 if self._state[1] in rev2branch:
825 for b in rev2branch[self._state[1]]: 814 for b in rev2branch[self._state[1]]:
826 if b.startswith('refs/remotes/origin/'): 815 if b.startswith('refs/remotes/origin/'):
827 return True 816 return True
828 for b, revision in branch2rev.iteritems(): 817 for b, revision in branch2rev.iteritems():