Mercurial > public > mercurial-scm > hg
comparison mercurial/subrepo.py @ 12992:2b73a3279a9f
subrepo: support for adding a git subrepo
gitsubrepo based on patch from David Soria Parra:
http://bitbucket.org/segv/davids-poor-git-subrepo-attempt/
author | Eric Eisner <ede@mit.edu> |
---|---|
date | Sun, 14 Nov 2010 18:15:26 -0500 |
parents | 9bb180abc4d0 |
children | a91334380699 |
comparison
equal
deleted
inserted
replaced
12991:23de1a7f8e82 | 12992:2b73a3279a9f |
---|---|
3 # Copyright 2009-2010 Matt Mackall <mpm@selenic.com> | 3 # Copyright 2009-2010 Matt Mackall <mpm@selenic.com> |
4 # | 4 # |
5 # This software may be used and distributed according to the terms of the | 5 # This software may be used and distributed according to the terms of the |
6 # GNU General Public License version 2 or any later version. | 6 # GNU General Public License version 2 or any later version. |
7 | 7 |
8 import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath | 8 import errno, os, re, xml.dom.minidom, shutil, subprocess, urlparse, posixpath |
9 from i18n import _ | 9 from i18n import _ |
10 import config, util, node, error, cmdutil | 10 import config, util, node, error, cmdutil |
11 hg = None | 11 hg = None |
12 | 12 |
13 nullstate = ('', '', 'empty') | 13 nullstate = ('', '', 'empty') |
574 | 574 |
575 def filedata(self, name): | 575 def filedata(self, name): |
576 return self._svncommand(['cat'], name) | 576 return self._svncommand(['cat'], name) |
577 | 577 |
578 | 578 |
579 class gitsubrepo(object): | |
580 def __init__(self, ctx, path, state): | |
581 # TODO add git version check. | |
582 self._state = state | |
583 self._ctx = ctx | |
584 self._path = ctx._repo.wjoin(path) | |
585 self._ui = ctx._repo.ui | |
586 | |
587 def _gitcommand(self, commands): | |
588 return self._gitdir(commands)[0] | |
589 | |
590 def _gitdir(self, commands): | |
591 commands = ['--no-pager', '--git-dir=%s/.git' % self._path, | |
592 '--work-tree=%s' % self._path] + commands | |
593 return self._gitnodir(commands) | |
594 | |
595 def _gitnodir(self, commands): | |
596 """Calls the git command | |
597 | |
598 The methods tries to call the git command. versions previor to 1.6.0 | |
599 are not supported and very probably fail. | |
600 """ | |
601 cmd = ['git'] + commands | |
602 cmd = [util.shellquote(arg) for arg in cmd] | |
603 cmd = util.quotecommand(' '.join(cmd)) | |
604 | |
605 # print git's stderr, which is mostly progress and useful info | |
606 p = subprocess.Popen(cmd, shell=True, bufsize=-1, | |
607 close_fds=(os.name == 'posix'), | |
608 stdout=subprocess.PIPE) | |
609 retdata = p.stdout.read() | |
610 # wait for the child to exit to avoid race condition. | |
611 p.wait() | |
612 | |
613 if p.returncode != 0: | |
614 # there are certain error codes that are ok | |
615 command = None | |
616 for arg in commands: | |
617 if not arg.startswith('-'): | |
618 command = arg | |
619 break | |
620 if command == 'cat-file': | |
621 return retdata, p.returncode | |
622 if command in ('commit', 'status') and p.returncode == 1: | |
623 return retdata, p.returncode | |
624 # for all others, abort | |
625 raise util.Abort('git %s error %d' % (command, p.returncode)) | |
626 | |
627 return retdata, p.returncode | |
628 | |
629 def _gitstate(self): | |
630 return self._gitcommand(['rev-parse', 'HEAD']).strip() | |
631 | |
632 def _githavelocally(self, revision): | |
633 out, code = self._gitdir(['cat-file', '-e', revision]) | |
634 return code == 0 | |
635 | |
636 def dirty(self): | |
637 if self._state[1] != self._gitstate(): # version checked out changed? | |
638 return True | |
639 # check for staged changes or modified files; ignore untracked files | |
640 # docs say --porcelain flag is future-proof format | |
641 changed = self._gitcommand(['status', '--porcelain', | |
642 '--untracked-files=no']) | |
643 return bool(changed.strip()) | |
644 | |
645 def commit(self, text, user, date): | |
646 cmd = ['commit', '-a', '-m', text] | |
647 if user: | |
648 cmd += ['--author', user] | |
649 if date: | |
650 # git's date parser silently ignores when seconds < 1e9 | |
651 # convert to ISO8601 | |
652 cmd += ['--date', util.datestr(date, '%Y-%m-%dT%H:%M:%S %1%2')] | |
653 self._gitcommand(cmd) | |
654 # make sure commit works otherwise HEAD might not exist under certain | |
655 # circumstances | |
656 return self._gitstate() | |
657 | |
579 types = { | 658 types = { |
580 'hg': hgsubrepo, | 659 'hg': hgsubrepo, |
581 'svn': svnsubrepo, | 660 'svn': svnsubrepo, |
661 'git': gitsubrepo, | |
582 } | 662 } |