diff options
author | Tommi Virtanen <tv@eagain.net> | 2007-09-01 17:47:42 -0700 |
---|---|---|
committer | Tommi Virtanen <tv@eagain.net> | 2007-09-01 18:06:45 -0700 |
commit | 0dbee1faddc65533c1d485f4b6d6693852db07c6 (patch) | |
tree | 6607cb1ea1bc9789a9b18a18500994b03e98a4f2 /gitosis/repository.py | |
parent | Use separate temp directories for separate tests. (diff) | |
download | gitosis-gentoo-0dbee1faddc65533c1d485f4b6d6693852db07c6.tar.gz gitosis-gentoo-0dbee1faddc65533c1d485f4b6d6693852db07c6.tar.bz2 gitosis-gentoo-0dbee1faddc65533c1d485f4b6d6693852db07c6.zip |
Add utilities for fast-import, exporting repository.
Redo subprocess error handling.
Diffstat (limited to 'gitosis/repository.py')
-rw-r--r-- | gitosis/repository.py | 106 |
1 files changed, 98 insertions, 8 deletions
diff --git a/gitosis/repository.py b/gitosis/repository.py index 17a8818..764c980 100644 --- a/gitosis/repository.py +++ b/gitosis/repository.py @@ -3,6 +3,15 @@ import subprocess from gitosis import util +class GitError(Exception): + """git failed""" + + def __str__(self): + return '%s: %s' % (self.__doc__, ': '.join(self.args)) + +class GitInitError(Exception): + """git init failed""" + def init( path, template=None, @@ -15,17 +24,98 @@ def init( args = [_git, 'init'] if template is not None: args.append('--template=%s' % template) - env = {} - env.update(os.environ) - env['GIT_DIR'] = '.' returncode = subprocess.call( args=args, cwd=path, close_fds=True, - env=env, + env=dict(GIT_DIR='.'), + ) + if returncode != 0: + raise GitInitError('exit status %d' % returncode) + + +class GitFastImportError(GitError): + """git fast-import failed""" + pass + +def fast_import( + git_dir, + commit_msg, + committer, + files, + ): + """ + Create an initial commit. + """ + init(path=git_dir) + child = subprocess.Popen( + args=['git', 'fast-import', '--quiet', '--date-format=now'], + cwd=git_dir, + stdin=subprocess.PIPE, + close_fds=True, + env=dict(GIT_DIR=git_dir), + ) + files = list(files) + for index, (path, content) in enumerate(files): + child.stdin.write("""\ +blob +mark :%(mark)d +data %(len)d +%(content)s +""" % dict( + mark=index+1, + len=len(content), + content=content, + )) + child.stdin.write("""\ +commit refs/heads/master +committer %(committer)s now +data %(commit_msg_len)d +%(commit_msg)s +""" % dict( + committer=committer, + commit_msg_len=len(commit_msg), + commit_msg=commit_msg, + )) + for index, (path, content) in enumerate(files): + child.stdin.write('M 100644 :%d %s\n' % (index+1, path)) + child.stdin.close() + returncode = child.wait() + if returncode != 0: + raise GitFastImportError( + 'git fast-import failed', 'exit status %d' % returncode) + +class GitExportError(GitError): + """Export failed""" + pass + +class GitReadTreeError(GitExportError): + """git read-tree failed""" + +class GitCheckoutIndexError(GitExportError): + """git checkout-index failed""" + +def export(git_dir, path): + # it's a literal prefix for git, a trailing slash is needed to + # extract to the subdirectory + path = os.path.join(path, '') + returncode = subprocess.call( + args=['git', 'read-tree', 'HEAD'], + close_fds=True, + env=dict(GIT_DIR=git_dir), + ) + if returncode != 0: + raise GitReadTreeError('exit status %d' % returncode) + returncode = subprocess.call( + args=[ + 'git', + 'checkout-index', + '-a', + '-f', + '--prefix=%s' % path, + ], + close_fds=True, + env=dict(GIT_DIR=git_dir), ) if returncode != 0: - raise RuntimeError( - ("Command '%r' returned non-zero exit status %d" - % (args, returncode)), - ) + raise GitCheckoutIndexError('exit status %d' % returncode) |