comparison mercurial/subrepo.py @ 12995:d90fc91c8377

subrepo: update and merge works with any git branch
author Eric Eisner <ede@mit.edu>
date Sun, 14 Nov 2010 18:31:29 -0500
parents 845c602b8635
children 3a42651b0a62
comparison
equal deleted inserted replaced
12994:845c602b8635 12995:d90fc91c8377
632 632
633 def _githavelocally(self, revision): 633 def _githavelocally(self, revision):
634 out, code = self._gitdir(['cat-file', '-e', revision]) 634 out, code = self._gitdir(['cat-file', '-e', revision])
635 return code == 0 635 return code == 0
636 636
637 def _gitbranchmap(self):
638 'returns the current branch and a map from git revision to branch[es]'
639 bm = {}
640 redirects = {}
641 current = None
642 out = self._gitcommand(['branch', '-a', '--no-color',
643 '--verbose', '--abbrev=40'])
644 for line in out.split('\n'):
645 if not line:
646 continue
647 if line[2:].startswith('(no branch)'):
648 continue
649 branch, revision = line[2:].split()[:2]
650 if revision == '->':
651 continue # ignore remote/HEAD redirects
652 if line[0] == '*':
653 current = branch
654 bm.setdefault(revision, []).append(branch)
655 return current, bm
656
637 def _fetch(self, source, revision): 657 def _fetch(self, source, revision):
638 if not os.path.exists('%s/.git' % self._path): 658 if not os.path.exists('%s/.git' % self._path):
639 self._ui.status(_('cloning subrepo %s\n') % self._relpath) 659 self._ui.status(_('cloning subrepo %s\n') % self._relpath)
640 self._gitnodir(['clone', source, self._path]) 660 self._gitnodir(['clone', source, self._path])
641 if self._githavelocally(revision): 661 if self._githavelocally(revision):
656 return bool(changed.strip()) 676 return bool(changed.strip())
657 677
658 def get(self, state): 678 def get(self, state):
659 source, revision, kind = state 679 source, revision, kind = state
660 self._fetch(source, revision) 680 self._fetch(source, revision)
661 if self._gitstate() != revision: 681 if self._gitstate() == revision:
682 return
683 current, bm = self._gitbranchmap()
684 if revision not in bm:
685 # no branch to checkout, check it out with no branch
662 self._ui.warn(_('checking out detached HEAD in subrepo %s\n') % 686 self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
663 self._relpath) 687 self._relpath)
664 self._ui.warn(_('check out a git branch if you intend ' 688 self._ui.warn(_('check out a git branch if you intend '
665 'to make changes\n')) 689 'to make changes\n'))
666 self._gitcommand(['checkout', '-q', revision]) 690 self._gitcommand(['checkout', '-q', revision])
691 return
692 branches = bm[revision]
693 firstlocalbranch = None
694 for b in branches:
695 if b == 'master':
696 # master trumps all other branches
697 self._gitcommand(['checkout', 'master'])
698 return
699 if not firstlocalbranch and not b.startswith('remotes/'):
700 firstlocalbranch = b
701 if firstlocalbranch:
702 self._gitcommand(['checkout', firstlocalbranch])
703 else:
704 remote = branches[0]
705 local = remote.split('/')[-1]
706 self._gitcommand(['checkout', '-b', local, remote])
667 707
668 def commit(self, text, user, date): 708 def commit(self, text, user, date):
669 cmd = ['commit', '-a', '-m', text] 709 cmd = ['commit', '-a', '-m', text]
670 if user: 710 if user:
671 cmd += ['--author', user] 711 cmd += ['--author', user]
690 730
691 def push(self, force): 731 def push(self, force):
692 cmd = ['push'] 732 cmd = ['push']
693 if force: 733 if force:
694 cmd.append('--force') 734 cmd.append('--force')
695 # as subrepos have no notion of "where to push to" we 735 # push the currently checked out branch
696 # assume origin master. This is git's default 736 current, bm = self._gitbranchmap()
697 self._gitcommand(cmd + ['origin', 'master', '-q']) 737 if current:
698 return True 738 self._gitcommand(cmd + ['origin', current, '-q'])
739 return True
740 else:
741 self._ui.warn(_('no branch checked out in subrepo %s\n'
742 'nothing to push') % self._relpath)
743 return False
699 744
700 types = { 745 types = {
701 'hg': hgsubrepo, 746 'hg': hgsubrepo,
702 'svn': svnsubrepo, 747 'svn': svnsubrepo,
703 'git': gitsubrepo, 748 'git': gitsubrepo,