7 from gitosis
import util
9 class GitError(Exception):
13 return '%s: %s' % (self
.__doc
__, ': '.join(self
.args
))
15 class GitInitError(Exception):
24 Create a git repository at C{path} (if missing).
26 Leading directories of C{path} must exist.
28 @param path: Path of repository create.
32 @param template: Template directory, to pass to C{git init}.
39 util
.mkdir(path
, 0750)
45 if template
is not None:
46 args
.append('--template=%s' % template
)
47 returncode
= subprocess
.call(
54 raise GitInitError('exit status %d' % returncode
)
57 class GitFastImportError(GitError
):
58 """git fast-import failed"""
69 Create an initial commit.
71 child
= subprocess
.Popen(
80 stdin
=subprocess
.PIPE
,
84 for index
, (path
, content
) in enumerate(files
):
85 child
.stdin
.write("""\
95 child
.stdin
.write("""\
96 commit refs/heads/master
97 committer %(committer)s now
98 data %(commit_msg_len)d
102 commit_msg_len
=len(commit_msg
),
103 commit_msg
=commit_msg
,
105 if parent
is not None:
106 assert not parent
.startswith(':')
107 child
.stdin
.write("""\
112 for index
, (path
, content
) in enumerate(files
):
113 child
.stdin
.write('M 100644 :%d %s\n' % (index
+1, path
))
115 returncode
= child
.wait()
117 raise GitFastImportError(
118 'git fast-import failed', 'exit status %d' % returncode
)
120 class GitExportError(GitError
):
124 class GitReadTreeError(GitExportError
):
125 """git read-tree failed"""
127 class GitCheckoutIndexError(GitExportError
):
128 """git checkout-index failed"""
130 def export(git_dir
, path
):
134 if e
.errno
== errno
.EEXIST
:
138 returncode
= subprocess
.call(
141 '--git-dir=%s' % git_dir
,
148 raise GitReadTreeError('exit status %d' % returncode
)
149 # jumping through hoops to be compatible with git versions
150 # that don't have --work-tree=
152 env
.update(os
.environ
)
153 env
['GIT_WORK_TREE'] = '.'
154 returncode
= subprocess
.call(
157 '--git-dir=%s' % os
.path
.abspath(git_dir
),
167 raise GitCheckoutIndexError('exit status %d' % returncode
)
169 class GitHasInitialCommitError(GitError
):
170 """Check for initial commit failed"""
172 class GitRevParseError(GitError
):
173 """rev-parse failed"""
175 def has_initial_commit(git_dir
):
176 child
= subprocess
.Popen(
184 stdout
=subprocess
.PIPE
,
187 got
= child
.stdout
.read()
188 returncode
= child
.wait()
190 raise GitRevParseError('exit status %d' % returncode
)
193 elif re
.match('^[0-9a-f]{40}\n$', got
):
196 raise GitHasInitialCommitError('Unknown git HEAD: %r' % got
)