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 pyarg_to_sha1(PyObject
*args
, unsigned char *sha1
)
28 if (!PyArg_ParseTuple(args
, "s", &hex
))
31 if (git_hex_to_sha1(hex
, sha1
)) {
40 sha1_to_pystr(unsigned char *sha1
)
42 char hex
[GIT_HEX_LENGTH
+ 1];
44 if (git_sha1_to_hex(sha1
, hex
))
47 return PyString_FromString(hex
);
56 struct git_commit
*commit
;
60 pygit_call_commit_op(struct git_commit
*commit
,
61 const char *(*commit_op
)(struct git_commit
*))
65 ret
= commit_op(commit
);
69 return PyString_FromString(ret
);
73 commit_message(GitCommitObject
*self
, PyObject
*args
)
76 return pygit_call_commit_op(self
->commit
, git_commit_message
);
80 commit_raw(GitCommitObject
*self
, PyObject
*args
)
83 return pygit_call_commit_op(self
->commit
, git_commit_raw
);
87 commit_id(GitCommitObject
*self
, PyObject
*args
)
90 unsigned char sha1
[GIT_SHA1_SIZE
];
94 err
= git_commit_id(self
->commit
, sha1
);
98 return sha1_to_pystr(sha1
);
101 static PyMethodDef commit_methods
[] = {
102 {"message", (PyCFunction
) commit_message
, METH_VARARGS
, NULL
},
103 {"id", (PyCFunction
) commit_id
, METH_VARARGS
, NULL
},
104 {"buffer", (PyCFunction
) commit_raw
, METH_VARARGS
, NULL
},
105 {NULL
, NULL
, 0, NULL
}
109 commit_dealloc(GitCommitObject
*self
)
111 git_commit_free(self
->commit
);
112 self
->ob_type
->tp_free((PyObject
*) self
);
116 commit_compare(GitCommitObject
*a
, GitCommitObject
*b
)
120 time_t a_time
, b_time
;
122 err
= git_commit_committer_date(a
->commit
, &a_time
, &a_tz
);
128 err
= git_commit_committer_date(b
->commit
, &b_time
, &b_tz
);
135 PyErr_SetString(PyGitError
, "time zone must be equal");
141 else if (a_time
> b_time
)
147 static PyTypeObject Git_Commit_Type
= {
148 PyObject_HEAD_INIT(NULL
)
150 "pygit.comit", /* tp_name */
151 sizeof(GitCommitObject
), /* tp_basicsize */
153 (destructor
)commit_dealloc
, /* tp_dealloc */
157 (cmpfunc
)commit_compare
, /* tp_compare */
159 0, /* tp_as_number */
160 0, /* tp_as_sequence */
161 0, /* tp_as_mapping */
167 0, /* tp_as_buffer */
168 Py_TPFLAGS_DEFAULT
, /* tp_flags */
172 0, /* tp_richcompare */
173 0, /* tp_weaklistoffset */
176 commit_methods
, /* tp_methods */
181 0, /* tp_descr_get */
182 0, /* tp_descr_set */
183 0, /* tp_dictoffset */
196 struct git_revlist_opt
*opt
;
200 revlist_free(GitRevListObject
*self
)
202 git_revlist_free(self
->opt
);
207 revlist_add_commit(GitRevListObject
*self
, PyObject
*args
, int exclude
)
210 unsigned char sha1
[GIT_SHA1_SIZE
];
212 err
= pyarg_to_sha1(args
, sha1
);
219 err
= git_revlist_exclude(self
->opt
, sha1
);
221 err
= git_revlist_include(self
->opt
, sha1
);
224 return pygit_error();
230 revlist_include(GitRevListObject
*self
, PyObject
*args
)
232 return revlist_add_commit(self
, args
, 0);
236 revlist_exclude(GitRevListObject
*self
, PyObject
*args
)
238 return revlist_add_commit(self
, args
, 1);
242 revlist_reverse(GitRevListObject
*self
, PyObject
*args
)
248 err
= git_revlist_reverse(self
->opt
);
250 return pygit_error();
256 revlist_show_merges(GitRevListObject
*self
, PyObject
*args
)
262 err
= git_revlist_show_merges(self
->opt
);
264 return pygit_error();
270 revlist_max_count(GitRevListObject
*self
, PyObject
*args
)
275 if (!PyArg_ParseTuple(args
, "k", &count
))
278 err
= git_revlist_max_count(self
->opt
, (size_t) count
);
280 return pygit_error();
285 static PyMethodDef revlist_methods
[] = {
286 {"include", (PyCFunction
) revlist_include
, METH_VARARGS
, NULL
},
287 {"exclude", (PyCFunction
) revlist_exclude
, METH_VARARGS
, NULL
},
288 {"reverse", (PyCFunction
) revlist_reverse
, METH_NOARGS
, NULL
},
289 {"show_merges", (PyCFunction
) revlist_show_merges
, METH_NOARGS
, NULL
},
290 {"max_count", (PyCFunction
) revlist_max_count
,METH_VARARGS
,NULL
},
291 {NULL
, NULL
, 0, NULL
}
295 revlist_dealloc(GitRevListObject
*self
)
297 git_revlist_free(self
->opt
);
298 self
->ob_type
->tp_free((PyObject
*) self
);
302 revlist_iter(GitRevListObject
*self
)
305 return (PyObject
*) self
;
309 revlist_iternext(GitRevListObject
*self
)
313 struct git_commit
*commit
;
315 commit
= git_commit_init();
317 return pygit_error();
319 ret
= git_revlist_next(self
->opt
, commit
);
321 git_commit_free(commit
);
322 if (!self
->list_end
) {
329 m
= PyObject_New(GitCommitObject
, &Git_Commit_Type
);
331 git_commit_free(commit
);
337 ret
= PyType_Ready(&Git_Commit_Type
);
343 return (PyObject
*) m
;
346 static PyTypeObject Git_RevList_Type
= {
347 PyObject_HEAD_INIT(NULL
)
349 "pygit.revlist", /* tp_name */
350 sizeof(GitRevListObject
), /* tp_basicsize */
352 (destructor
)revlist_dealloc
, /* tp_dealloc */
358 0, /* tp_as_number */
359 0, /* tp_as_sequence */
360 0, /* tp_as_mapping */
366 0, /* tp_as_buffer */
367 Py_TPFLAGS_DEFAULT
, /* tp_flags */
371 0, /* tp_richcompare */
372 0, /* tp_weaklistoffset */
373 (getiterfunc
)revlist_iter
, /* tp_iter */
374 (iternextfunc
)revlist_iternext
, /* tp_iternext */
375 revlist_methods
, /* tp_methods */
380 0, /* tp_descr_get */
381 0, /* tp_descr_set */
382 0, /* tp_dictoffset */
398 repo_read_obj(PyObject
*args
,
399 int (*read_obj
)(unsigned char *sha1
, void **buf
, size_t *len
))
404 unsigned char sha1
[GIT_SHA1_SIZE
];
406 err
= pyarg_to_sha1(args
, sha1
);
410 err
= read_obj(sha1
, &buf
, NULL
);
412 return pygit_error();
414 ret
= PyString_FromString((char *) buf
);
421 repo_head_commit(GitRepoObject
*self
, PyObject
*args
)
424 unsigned char sha1
[GIT_SHA1_SIZE
];
429 err
= git_repo_head(sha1
);
431 return pygit_error();
433 return sha1_to_pystr(sha1
);
437 repo_read_commit(GitRepoObject
*self
, PyObject
*args
)
440 return repo_read_obj(args
, git_repo_commit_read
);
444 repo_read_blob(GitRepoObject
*self
, PyObject
*args
)
447 return repo_read_obj(args
, git_repo_blob_read
);
451 repo_lookup_commit(GitRepoObject
*self
, PyObject
*args
)
455 struct git_commit
*commit
;
456 unsigned char sha1
[GIT_SHA1_SIZE
];
460 err
= pyarg_to_sha1(args
, sha1
);
464 commit
= git_commit_lookup(sha1
);
466 return pygit_error();
468 m
= PyObject_New(GitCommitObject
, &Git_Commit_Type
);
470 git_commit_free(commit
);
476 err
= PyType_Ready(&Git_Commit_Type
);
482 return (PyObject
*) m
;
486 repo_translate_ref(GitRepoObject
*self
, PyObject
*args
)
490 unsigned char sha1
[GIT_SHA1_SIZE
];
494 if (!PyArg_ParseTuple(args
, "s", &ref
))
497 err
= git_repo_translate_ref(ref
, sha1
);
499 return pygit_error();
501 return sha1_to_pystr(sha1
);
505 repo_revlist(GitRepoObject
*self
, PyObject
*args
)
513 m
= PyObject_New(GitRevListObject
, &Git_RevList_Type
);
517 err
= PyType_Ready(&Git_RevList_Type
);
523 m
->opt
= git_revlist_init();
526 return pygit_error();
530 return (PyObject
*) m
;
533 static PyMethodDef repo_methods
[] = {
534 {"read_commit", (PyCFunction
) repo_read_commit
, METH_VARARGS
, NULL
},
535 {"read_blob", (PyCFunction
) repo_read_blob
, METH_VARARGS
, NULL
},
536 {"lookup_commit", (PyCFunction
) repo_lookup_commit
, METH_VARARGS
,NULL
},
537 {"head_commit", (PyCFunction
) repo_head_commit
, METH_NOARGS
, NULL
},
538 {"translate_ref", (PyCFunction
) repo_translate_ref
,METH_VARARGS
, NULL
},
539 {"revlist", (PyCFunction
) repo_revlist
, METH_VARARGS
, NULL
},
540 {NULL
, NULL
, 0, NULL
}
543 static PyMemberDef repo_members
[] = {
544 {"path", T_OBJECT_EX
, offsetof(GitRepoObject
, path
), 0,
545 "repository's path"},
546 {NULL
, 0, 0, 0, NULL
}
550 repo_dealloc(GitRepoObject
*self
)
552 Py_XDECREF(self
->path
);
553 self
->ob_type
->tp_free((PyObject
*) self
);
556 static PyTypeObject Git_Repo_Type
= {
557 PyObject_HEAD_INIT(NULL
)
559 "pygit.repo", /* tp_name */
560 sizeof(GitRepoObject
), /* tp_basicsize */
562 (destructor
)repo_dealloc
, /* tp_dealloc */
568 0, /* tp_as_number */
569 0, /* tp_as_sequence */
570 0, /* tp_as_mapping */
576 0, /* tp_as_buffer */
577 Py_TPFLAGS_DEFAULT
, /* tp_flags */
581 0, /* tp_richcompare */
582 0, /* tp_weaklistoffset */
585 repo_methods
, /* tp_methods */
586 repo_members
, /* tp_members */
590 0, /* tp_descr_get */
591 0, /* tp_descr_set */
592 0, /* tp_dictoffset */
603 pygit_open(PyObject
*self
, PyObject
*args
)
611 if (!PyArg_ParseTuple(args
, "s", &dir
))
614 err
= git_repo_open(dir
);
616 return pygit_error();
618 m
= PyObject_New(GitRepoObject
, &Git_Repo_Type
);
622 err
= PyType_Ready(&Git_Repo_Type
);
628 m
->path
= PyString_FromString(dir
);
634 return (PyObject
*) m
;
637 static PyMethodDef pygit_methods
[] = {
638 { "open", pygit_open
, METH_VARARGS
, "Open a GIT repository" },
639 { NULL
, NULL
, 0, NULL
}
647 m
= Py_InitModule("pygit", pygit_methods
);
651 PyGitError
= PyErr_NewException("pygit.error", NULL
, NULL
);
655 Py_INCREF(PyGitError
);
656 PyModule_AddObject(m
, "error", PyGitError
);