From: "Karl Hasselström" <kha@treskal.com>
To: Catalin Marinas <catalin.marinas@gmail.com>
Cc: git@vger.kernel.org
Subject: [StGit PATCH] Read several objects at once with git cat-file --batch
Date: Fri, 08 Aug 2008 10:07:04 +0200 [thread overview]
Message-ID: <20080808080614.23424.28169.stgit@yoghurt> (raw)
In-Reply-To: <20080808082728.GA24017@diana.vm.bytemark.co.uk>
Instead of spawning a separate cat-file process for every blob and
commit we want to read. This speeds things up slightly: about 6-8%
when uncommitting and rebasing 1470 linux-kernel patches (perftest.py
rebase-newrebase-add-file-linux).
Signed-off-by: Karl Hasselström <kha@treskal.com>
---
stgit/lib/git.py | 34 +++++++++++++++++++++++++++++++++-
stgit/run.py | 17 +++++++++++++++++
2 files changed, 50 insertions(+), 1 deletions(-)
diff --git a/stgit/lib/git.py b/stgit/lib/git.py
index 648e190..95efd9a 100644
--- a/stgit/lib/git.py
+++ b/stgit/lib/git.py
@@ -520,6 +520,37 @@ class RunWithEnvCwd(RunWithEnv):
@param args: Command and argument vector"""
return RunWithEnv.run(self, args, self.env_in_cwd)
+class CatFileProcess(object):
+ def __init__(self, repo):
+ self.__repo = repo
+ self.__proc = None
+ def __get_process(self):
+ if not self.__proc:
+ self.__proc = self.__repo.run(['git', 'cat-file', '--batch']
+ ).run_background()
+ return self.__proc
+ def cat_file(self, sha1):
+ p = self.__get_process()
+ p.stdin.write('%s\n' % sha1)
+ p.stdin.flush()
+
+ # Read until we have the entire status line.
+ s = ''
+ while not '\n' in s:
+ s += os.read(p.stdout.fileno(), 4096)
+ h, b = s.split('\n', 1)
+ if h == '%s missing' % sha1:
+ raise SomeException()
+ hash, type, length = h.split()
+ assert hash == sha1
+ length = int(length)
+
+ # Read until we have the entire object plus the trailing
+ # newline.
+ while len(b) < length + 1:
+ b += os.read(p.stdout.fileno(), 4096)
+ return type, b[:-1]
+
class Repository(RunWithEnv):
"""Represents a git repository."""
def __init__(self, directory):
@@ -531,6 +562,7 @@ class Repository(RunWithEnv):
self.__default_index = None
self.__default_worktree = None
self.__default_iw = None
+ self.__catfile = CatFileProcess(self)
env = property(lambda self: { 'GIT_DIR': self.__git_dir })
@classmethod
def default(cls):
@@ -580,7 +612,7 @@ class Repository(RunWithEnv):
directory = property(lambda self: self.__git_dir)
refs = property(lambda self: self.__refs)
def cat_object(self, sha1):
- return self.run(['git', 'cat-file', '-p', sha1]).raw_output()
+ return self.__catfile.cat_file(sha1)[1]
def rev_parse(self, rev):
try:
return self.get_commit(self.run(
diff --git a/stgit/run.py b/stgit/run.py
index 7493ed3..ccca059 100644
--- a/stgit/run.py
+++ b/stgit/run.py
@@ -130,6 +130,19 @@ class Run:
raise self.exc('%s failed: %s' % (self.__cmd[0], e))
self.__log_end(self.exitcode)
self.__check_exitcode()
+ def __run_background(self):
+ """Run in background."""
+ assert self.__indata == None
+ try:
+ p = subprocess.Popen(self.__cmd, env = self.__env, cwd = self.__cwd,
+ stdin = subprocess.PIPE,
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE)
+ except OSError, e:
+ raise self.exc('%s failed: %s' % (self.__cmd[0], e))
+ self.stdin = p.stdin
+ self.stdout = p.stdout
+ self.stderr = p.stderr
def returns(self, retvals):
self.__good_retvals = retvals
return self
@@ -181,6 +194,10 @@ class Run:
def run(self):
"""Just run, with no IO redirection."""
self.__run_noio()
+ def run_background(self):
+ """Run as a background process."""
+ self.__run_background()
+ return self
def xargs(self, xargs):
"""Just run, with no IO redirection. The extra arguments are
appended to the command line a few at a time; the command is
next prev parent reply other threads:[~2008-08-08 8:08 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-08 8:27 [StGit] kha/{safe,experimental} updated Karl Hasselström
2008-08-08 8:07 ` Karl Hasselström [this message]
2008-08-10 22:25 ` [StGit PATCH] Read several objects at once with git cat-file --batch Catalin Marinas
2008-08-10 23:58 ` Karl Hasselström
2008-08-13 21:54 ` [StGit] kha/{safe,experimental} updated Catalin Marinas
2008-08-17 20:18 ` Karl Hasselström
2008-08-21 22:16 ` Catalin Marinas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080808080614.23424.28169.stgit@yoghurt \
--to=kha@treskal.com \
--cc=catalin.marinas@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox