2 #include "structmember.h"
4 #include <libgit-thin.h>
6 static PyObject
*PyGitError
;
8 PyMODINIT_FUNC
initpygit(void);
11 * Useful helpers for all the types
14 #define UNUSED(x) (x = x)
19 return PyErr_Format(PyGitError
, "[Errno: %d] %s", errno
,
24 pygit_error_revlist(void)
26 PyErr_SetString(PyGitError
, "revlist not configured");
31 pyarg_to_sha1(PyObject
*args
, unsigned char *sha1
)
35 if (!PyArg_ParseTuple(args
, "s", &hex
))
38 if (git_hex_to_sha1(hex
, sha1
)) {
47 sha1_to_pystr(unsigned char *sha1
)
49 char hex
[GIT_HEX_LENGTH
+ 1];
51 if (git_sha1_to_hex(sha1
, hex
))
54 return PyString_FromString(hex
);
63 struct git_commit
*commit
;
67 pygit_call_commit_op(struct git_commit
*commit
,
68 const char *(*commit_op
)(struct git_commit
*))
72 ret
= commit_op(commit
);
76 return PyString_FromString(ret
);
80 pygit_commit_message(GitCommitObject
*self
, PyObject
*args
)
83 return pygit_call_commit_op(self
->commit
, git_commit_message
);
87 pygit_commit_raw(GitCommitObject
*self
, PyObject
*args
)
90 return pygit_call_commit_op(self
->commit
, git_commit_raw
);
94 pygit_commit_id(GitCommitObject
*self
, PyObject
*args
)
97 unsigned char sha1
[GIT_SHA1_SIZE
];
101 err
= git_commit_id(self
->commit
, sha1
);
103 return pygit_error();
105 return sha1_to_pystr(sha1
);
108 static PyMethodDef git_commit_methods
[] = {
109 {"message", (PyCFunction
) pygit_commit_message
, METH_VARARGS
, NULL
},
110 {"id", (PyCFunction
) pygit_commit_id
, METH_VARARGS
, NULL
},
111 {"buffer", (PyCFunction
) pygit_commit_raw
, METH_VARARGS
, NULL
},
112 {NULL
, NULL
, 0, NULL
}
116 git_commit_dealloc(GitCommitObject
*self
)
118 git_commit_free(self
->commit
);
119 self
->ob_type
->tp_free((PyObject
*) self
);
122 static PyTypeObject Git_Commit_Type
= {
123 PyObject_HEAD_INIT(NULL
)
125 "pygit.comit", /* tp_name */
126 sizeof(GitCommitObject
), /* tp_basicsize */
128 (destructor
)git_commit_dealloc
, /* tp_dealloc */
134 0, /* tp_as_number */
135 0, /* tp_as_sequence */
136 0, /* tp_as_mapping */
142 0, /* tp_as_buffer */
143 Py_TPFLAGS_DEFAULT
, /* tp_flags */
147 0, /* tp_richcompare */
148 0, /* tp_weaklistoffset */
151 git_commit_methods
, /* tp_methods */
156 0, /* tp_descr_get */
157 0, /* tp_descr_set */
158 0, /* tp_dictoffset */
171 struct git_revlist_opt
*revlist_opt
;
175 repo_read_obj(PyObject
*args
,
176 int (*read_obj
)(unsigned char *sha1
, void **buf
, size_t *len
))
181 unsigned char sha1
[GIT_SHA1_SIZE
];
183 err
= pyarg_to_sha1(args
, sha1
);
187 err
= read_obj(sha1
, &buf
, NULL
);
189 return pygit_error();
191 ret
= PyString_FromString((char *) buf
);
198 pygit_repo_head_commit(GitRepoObject
*self
, PyObject
*args
)
201 unsigned char sha1
[GIT_SHA1_SIZE
];
206 err
= git_repo_head(sha1
);
208 return pygit_error();
210 return sha1_to_pystr(sha1
);
214 pygit_repo_read_commit(GitRepoObject
*self
, PyObject
*args
)
217 return repo_read_obj(args
, git_repo_commit_read
);
221 pygit_repo_read_blob(GitRepoObject
*self
, PyObject
*args
)
224 return repo_read_obj(args
, git_repo_blob_read
);
228 pygit_repo_lookup_commit(GitRepoObject
*self
, PyObject
*args
)
232 struct git_commit
*commit
;
233 unsigned char sha1
[GIT_SHA1_SIZE
];
237 err
= pyarg_to_sha1(args
, sha1
);
241 commit
= git_commit_lookup(sha1
);
243 return pygit_error();
245 m
= PyObject_New(GitCommitObject
, &Git_Commit_Type
);
247 git_commit_free(commit
);
253 err
= PyType_Ready(&Git_Commit_Type
);
259 return (PyObject
*) m
;
263 pygit_repo_revlist_include(GitRepoObject
*self
, PyObject
*args
)
266 unsigned char sha1
[GIT_SHA1_SIZE
];
268 if (!self
->revlist_opt
) {
269 self
->revlist_opt
= git_revlist_init();
270 if (!self
->revlist_opt
)
271 return pygit_error();
274 err
= pyarg_to_sha1(args
, sha1
);
276 git_revlist_free(self
->revlist_opt
);
277 self
->revlist_opt
= NULL
;
281 err
= git_revlist_include(self
->revlist_opt
, sha1
);
283 return pygit_error();
289 pygit_repo_translate_ref(GitRepoObject
*self
, PyObject
*args
)
293 unsigned char sha1
[GIT_SHA1_SIZE
];
297 if (!PyArg_ParseTuple(args
, "s", &ref
))
300 err
= git_repo_translate_ref(ref
, sha1
);
302 return pygit_error();
304 return sha1_to_pystr(sha1
);
307 static PyMethodDef git_repo_methods
[] = {
308 {"read_commit", (PyCFunction
) pygit_repo_read_commit
,
310 {"read_blob", (PyCFunction
) pygit_repo_read_blob
,
312 {"lookup_commit", (PyCFunction
) pygit_repo_lookup_commit
,
314 {"head_commit", (PyCFunction
) pygit_repo_head_commit
, METH_NOARGS
,
316 {"revlist_include", (PyCFunction
) pygit_repo_revlist_include
,
318 {"translate_ref", (PyCFunction
) pygit_repo_translate_ref
,
320 {NULL
, NULL
, 0, NULL
}
323 static PyMemberDef git_repo_members
[] = {
324 {"path", T_OBJECT_EX
, offsetof(GitRepoObject
, path
), 0,
325 "repository's path"},
326 {NULL
, 0, 0, 0, NULL
}
330 git_repo_dealloc(GitRepoObject
*self
)
332 Py_XDECREF(self
->path
);
333 git_revlist_free(self
->revlist_opt
);
334 self
->ob_type
->tp_free((PyObject
*) self
);
338 git_repo_iter(GitRepoObject
*self
)
340 if (!self
->revlist_opt
)
341 return pygit_error_revlist();
344 return (PyObject
*) self
;
348 git_repo_iternext(GitRepoObject
*self
)
352 struct git_commit
*commit
;
354 if (!self
->revlist_opt
)
355 return pygit_error_revlist();
357 commit
= git_commit_init();
359 return pygit_error();
361 ret
= git_revlist_next(self
->revlist_opt
, commit
);
363 git_commit_free(commit
);
368 m
= PyObject_New(GitCommitObject
, &Git_Commit_Type
);
370 git_commit_free(commit
);
377 ret
= PyType_Ready(&Git_Commit_Type
);
384 return (PyObject
*) m
;
387 static PyTypeObject Git_Repo_Type
= {
388 PyObject_HEAD_INIT(NULL
)
390 "pygit.repo", /* tp_name */
391 sizeof(GitRepoObject
), /* tp_basicsize */
393 (destructor
)git_repo_dealloc
, /* tp_dealloc */
399 0, /* tp_as_number */
400 0, /* tp_as_sequence */
401 0, /* tp_as_mapping */
407 0, /* tp_as_buffer */
408 Py_TPFLAGS_DEFAULT
, /* tp_flags */
412 0, /* tp_richcompare */
413 0, /* tp_weaklistoffset */
414 (getiterfunc
)git_repo_iter
, /* tp_iter */
415 (iternextfunc
)git_repo_iternext
, /* tp_iternext */
416 git_repo_methods
, /* tp_methods */
417 git_repo_members
, /* tp_members */
421 0, /* tp_descr_get */
422 0, /* tp_descr_set */
423 0, /* tp_dictoffset */
430 pygit_open(PyObject
*self
, PyObject
*args
)
438 if (!PyArg_ParseTuple(args
, "s", &dir
))
441 err
= git_repo_open(dir
);
443 return pygit_error();
445 m
= PyObject_New(GitRepoObject
, &Git_Repo_Type
);
449 err
= PyType_Ready(&Git_Repo_Type
);
455 m
->path
= PyString_FromString(dir
);
460 m
->revlist_opt
= NULL
;
462 return (PyObject
*) m
;
469 static PyMethodDef pygit_methods
[] = {
470 { "open", pygit_open
, METH_VARARGS
, "Open a GIT repository" },
471 { NULL
, NULL
, 0, NULL
}
479 m
= Py_InitModule("pygit", pygit_methods
);
483 PyGitError
= PyErr_NewException("pygit.error", NULL
, NULL
);
487 Py_INCREF(PyGitError
);
488 PyModule_AddObject(m
, "error", PyGitError
);