changeset 2676:1f4d4b8d72f5 beta

switched git_command to subprocession for non-blocking Popen.
author Marcin Kuzminski <marcin@python-works.com>
date Mon, 30 Jul 2012 22:45:43 +0200
parents 31265f80cf8b
children 4fbbc65e8cd5
files rhodecode/lib/subprocessio.py rhodecode/lib/vcs/backends/git/repository.py
diffstat 2 files changed, 26 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/lib/subprocessio.py	Fri Jul 27 01:36:01 2012 +0200
+++ b/rhodecode/lib/subprocessio.py	Mon Jul 30 22:45:43 2012 +0200
@@ -338,6 +338,9 @@
             input_streamer.start()
             inputstream = input_streamer.output
 
+        if isinstance(cmd, (list, tuple)):
+            cmd = ' '.join(cmd)
+
         _p = subprocess.Popen(cmd,
             bufsize=-1,
             shell=True,
@@ -367,8 +370,8 @@
                 pass
             bg_out.stop()
             bg_err.stop()
-            err = '%r' % ''.join(bg_err)
-            raise EnvironmentError("Subprocess exited due to an error.\n" + err)
+            err = '%s' % ''.join(bg_err)
+            raise EnvironmentError("Subprocess exited due to an error:\n" + err)
 
         self.process = _p
         self.output = bg_out
@@ -379,7 +382,7 @@
 
     def next(self):
         if self.process.poll():
-            err = '%r' % ''.join(self.error)
+            err = '%s' % ''.join(self.error)
             raise EnvironmentError("Subprocess exited due to an error:\n" + err)
         return self.output.next()
 
--- a/rhodecode/lib/vcs/backends/git/repository.py	Fri Jul 27 01:36:01 2012 +0200
+++ b/rhodecode/lib/vcs/backends/git/repository.py	Mon Jul 30 22:45:43 2012 +0200
@@ -13,6 +13,8 @@
 import re
 import time
 import posixpath
+import logging
+import traceback
 from dulwich.repo import Repo, NotGitRepository
 #from dulwich.config import ConfigFile
 from string import Template
@@ -33,6 +35,10 @@
 from .changeset import GitChangeset
 from .inmemory import GitInMemoryChangeset
 from .config import ConfigFile
+from rhodecode.lib import subprocessio
+
+
+log = logging.getLogger(__name__)
 
 
 class GitRepository(BaseRepository):
@@ -106,22 +112,18 @@
             cmd = ' '.join(cmd)
         try:
             opts = dict(
-                shell=isinstance(cmd, basestring),
-                stdout=PIPE,
-                stderr=PIPE,
                 env=gitenv,
             )
             if os.path.isdir(self.path):
                 opts['cwd'] = self.path
-            p = Popen(cmd, **opts)
-        except OSError, err:
+            p = subprocessio.SubprocessIOChunker(cmd, **opts)
+        except (EnvironmentError, OSError), err:
+            log.error(traceback.format_exc())
             raise RepositoryError("Couldn't run git command (%s).\n"
-                "Original error was:%s" % (cmd, err))
-        so, se = p.communicate()
-        if not se.startswith("fatal: bad default revision 'HEAD'") and \
-            p.returncode != 0:
-            raise RepositoryError("Couldn't run git command (%s).\n"
-                "stderr:\n%s" % (cmd, se))
+                                  "Original error was:%s" % (cmd, err))
+
+        so = ''.join(p)
+        se = None
         return so, se
 
     def _check_url(self, url):
@@ -161,6 +163,13 @@
             raise RepositoryError(err)
 
     def _get_all_revisions(self):
+        # we must check if this repo is not empty, since later command
+        # fails if it is. And it's cheaper to ask than throw the subprocess
+        # errors
+        try:
+            self._repo.head()
+        except KeyError:
+            return []
         cmd = 'rev-list --all --reverse --date-order'
         try:
             so, se = self.run_git_command(cmd)