comparison mercurial/subrepo.py @ 13029:f930032aa6d5

subrepo: lazier git push logic Avoids calls to git push when the revision is already known to be in the remote repository. Now, when using a read-only git subrepo, git will never need to talk to its upstream repository.
author Eric Eisner <ede@mit.edu>
date Sun, 21 Nov 2010 22:00:51 -0500
parents 7f2ecb64140d
children b4814f1f415c
comparison
equal deleted inserted replaced
13028:687006f06e00 13029:f930032aa6d5
663 663
664 def _githavelocally(self, revision): 664 def _githavelocally(self, revision):
665 out, code = self._gitdir(['cat-file', '-e', revision]) 665 out, code = self._gitdir(['cat-file', '-e', revision])
666 return code == 0 666 return code == 0
667 667
668 def _gitisancestor(self, r1, r2):
669 base = self._gitcommand(['merge-base', r1, r2]).strip()
670 return base == r1
671
668 def _gitbranchmap(self): 672 def _gitbranchmap(self):
669 'returns the current branch and a map from git revision to branch[es]' 673 'returns the current branch and a map from git revision to branch[es]'
670 bm = {} 674 bm = {}
671 redirects = {} 675 redirects = {}
672 current = None 676 current = None
765 self.get(state) # fast forward merge 769 self.get(state) # fast forward merge
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):
774 # if a branch in origin contains the revision, nothing to do
775 current, bm = self._gitbranchmap()
776 for revision, branches in bm.iteritems():
777 for b in branches:
778 if b.startswith('remotes/origin'):
779 if self._gitisancestor(self._state[1], revision):
780 return True
781 # otherwise, try to push the currently checked out branch
770 cmd = ['push'] 782 cmd = ['push']
771 if force: 783 if force:
772 cmd.append('--force') 784 cmd.append('--force')
773 # push the currently checked out branch
774 current, bm = self._gitbranchmap()
775 if current: 785 if current:
786 # determine if the current branch is even useful
787 if not self._gitisancestor(self._state[1], current):
788 self._ui.warn(_('unrelated git branch checked out '
789 'in subrepo %s\n') % self._relpath)
790 return False
791 self._ui.status(_('pushing branch %s of subrepo %s\n') %
792 (current, self._relpath))
776 self._gitcommand(cmd + ['origin', current, '-q']) 793 self._gitcommand(cmd + ['origin', current, '-q'])
777 return True 794 return True
778 else: 795 else:
779 self._ui.warn(_('no branch checked out in subrepo %s\n' 796 self._ui.warn(_('no branch checked out in subrepo %s\n'
780 'nothing to push') % self._relpath) 797 'cannot push revision %s') %
798 (self._relpath, self._state[1]))
781 return False 799 return False
782 800
783 def remove(self): 801 def remove(self):
784 if self.dirty(): 802 if self.dirty():
785 self._ui.warn(_('not removing repo %s because ' 803 self._ui.warn(_('not removing repo %s because '