hgext/convert/git.py
changeset 18570 dcf2d6fdf630
parent 17930 7788b5e7d9ef
child 18572 5fe58f9332a4
equal deleted inserted replaced
18569:11bcab177d22 18570:dcf2d6fdf630
     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 os
     8 import os
       
     9 import subprocess
     9 from mercurial import util, config
    10 from mercurial import util, config
    10 from mercurial.node import hex, nullid
    11 from mercurial.node import hex, nullid
    11 from mercurial.i18n import _
    12 from mercurial.i18n import _
    12 
    13 
    13 from common import NoRepo, commit, converter_source, checktool
    14 from common import NoRepo, commit, converter_source, checktool
    27 class convert_git(converter_source):
    28 class convert_git(converter_source):
    28     # Windows does not support GIT_DIR= construct while other systems
    29     # Windows does not support GIT_DIR= construct while other systems
    29     # cannot remove environment variable. Just assume none have
    30     # cannot remove environment variable. Just assume none have
    30     # both issues.
    31     # both issues.
    31     if util.safehasattr(os, 'unsetenv'):
    32     if util.safehasattr(os, 'unsetenv'):
    32         def gitopen(self, s, noerr=False):
    33         def gitopen(self, s, err=None):
    33             prevgitdir = os.environ.get('GIT_DIR')
    34             prevgitdir = os.environ.get('GIT_DIR')
    34             os.environ['GIT_DIR'] = self.path
    35             os.environ['GIT_DIR'] = self.path
    35             try:
    36             try:
    36                 if noerr:
    37                 if err == subprocess.PIPE:
    37                     (stdin, stdout, stderr) = util.popen3(s)
    38                     (stdin, stdout, stderr) = util.popen3(s)
    38                     return stdout
    39                     return stdout
       
    40                 elif err == subprocess.STDOUT:
       
    41                     return self.popen_with_stderr(s)
    39                 else:
    42                 else:
    40                     return util.popen(s, 'rb')
    43                     return util.popen(s, 'rb')
    41             finally:
    44             finally:
    42                 if prevgitdir is None:
    45                 if prevgitdir is None:
    43                     del os.environ['GIT_DIR']
    46                     del os.environ['GIT_DIR']
    44                 else:
    47                 else:
    45                     os.environ['GIT_DIR'] = prevgitdir
    48                     os.environ['GIT_DIR'] = prevgitdir
    46     else:
    49     else:
    47         def gitopen(self, s, noerr=False):
    50         def gitopen(self, s, err=None):
    48             if noerr:
    51             if err == subprocess.PIPE:
    49                 (sin, so, se) = util.popen3('GIT_DIR=%s %s' % (self.path, s))
    52                 (sin, so, se) = util.popen3('GIT_DIR=%s %s' % (self.path, s))
    50                 return so
    53                 return so
       
    54             elif err == subprocess.STDOUT:
       
    55                     return self.popen_with_stderr(s)
    51             else:
    56             else:
    52                 return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
    57                 return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
       
    58 
       
    59     def popen_with_stderr(self, s):
       
    60         p = subprocess.Popen(s, shell=True, bufsize=-1,
       
    61                              close_fds=util.closefds,
       
    62                              stdin=subprocess.PIPE,
       
    63                              stdout=subprocess.PIPE,
       
    64                              stderr=subprocess.STDOUT,
       
    65                              universal_newlines=False,
       
    66                              env=None)
       
    67         return p.stdout
    53 
    68 
    54     def gitread(self, s):
    69     def gitread(self, s):
    55         fh = self.gitopen(s)
    70         fh = self.gitopen(s)
    56         data = fh.read()
    71         data = fh.read()
    57         return data, fh.close()
    72         return data, fh.close()
   207         return c
   222         return c
   208 
   223 
   209     def gettags(self):
   224     def gettags(self):
   210         tags = {}
   225         tags = {}
   211         alltags = {}
   226         alltags = {}
   212         fh = self.gitopen('git ls-remote --tags "%s"' % self.path)
   227         fh = self.gitopen('git ls-remote --tags "%s"' % self.path,
       
   228                           err=subprocess.STDOUT)
   213         prefix = 'refs/tags/'
   229         prefix = 'refs/tags/'
   214 
   230 
   215         # Build complete list of tags, both annotated and bare ones
   231         # Build complete list of tags, both annotated and bare ones
   216         for line in fh:
   232         for line in fh:
   217             line = line.strip()
   233             line = line.strip()
       
   234             if line.startswith("error:"):
       
   235                 raise util.Abort(_('cannot read tags from %s') % self.path)
   218             node, tag = line.split(None, 1)
   236             node, tag = line.split(None, 1)
   219             if not tag.startswith(prefix):
   237             if not tag.startswith(prefix):
   220                 continue
   238                 continue
   221             alltags[tag[len(prefix):]] = node
   239             alltags[tag[len(prefix):]] = node
   222         if fh.close():
   240         if fh.close():
   264                           '': 'git show-ref'}
   282                           '': 'git show-ref'}
   265 
   283 
   266         # Origin heads
   284         # Origin heads
   267         for reftype in gitcmd:
   285         for reftype in gitcmd:
   268             try:
   286             try:
   269                 fh = self.gitopen(gitcmd[reftype], noerr=True)
   287                 fh = self.gitopen(gitcmd[reftype], err=subprocess.PIPE)
   270                 for line in fh:
   288                 for line in fh:
   271                     line = line.strip()
   289                     line = line.strip()
   272                     rev, name = line.split(None, 1)
   290                     rev, name = line.split(None, 1)
   273                     if not name.startswith(prefix):
   291                     if not name.startswith(prefix):
   274                         continue
   292                         continue