Mercurial > public > mercurial-scm > hg-stable
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, |