Adjust to libgit2 development branch

This wraps the previous functionality, though there are some iterator
changes we might still want to bring over.
This commit is contained in:
Carlos Martín Nieto 2013-10-30 08:57:17 +01:00
parent c267891d1f
commit b7e906eee9
12 changed files with 87 additions and 116 deletions

View File

@ -49,9 +49,8 @@ def init_repository(path, bare=False):
def clone_repository(
url, path, bare=False, remote_name="origin",
push_url=None, fetch_spec=None,
push_spec=None, checkout_branch=None):
url, path, bare=False, ignore_cert_errors=False,
remote_name="origin", checkout_branch=None):
"""
Clones a new Git repository from *url* in the given *path*.
@ -60,15 +59,6 @@ def clone_repository(
**remote_name** is the name given to the "origin" remote.
The default is "origin".
**push_url** is a URL to be used for pushing.
None means use the *url* parameter.
**fetch_spec** defines the the default fetch spec.
None results in the same behavior as *GIT_REMOTE_DEFAULT_FETCH*.
**push_spec** is the fetch specification to be used for pushing.
None means use the same spec as for *fetch_spec*.
**checkout_branch** gives the name of the branch to checkout.
None means use the remote's *HEAD*.
@ -83,6 +73,5 @@ def clone_repository(
"""
_pygit2.clone_repository(
url, path, bare, remote_name, push_url,
fetch_spec, push_spec, checkout_branch)
url, path, bare, ignore_cert_errors, remote_name, checkout_branch)
return Repository(path)

View File

@ -336,55 +336,44 @@ PyDoc_STRVAR(Config_get_multivar__doc__,
"parameter is expected to be a regular expression to filter the variables\n"
"we're interested in.");
int
Config_get_multivar_fn_wrapper(const git_config_entry *value, void *data)
{
PyObject *item;
item = to_unicode(value->value, NULL, NULL);
if (item == NULL)
/* FIXME Right now there is no way to forward errors through the
* libgit2 API, open an issue or pull-request to libgit2.
*
* See libgit2/src/config_file.c:443 (config_get_multivar).
* Comment says "early termination by the user is not an error".
* That's wrong.
*/
return -2;
PyList_Append((PyObject *)data, item);
Py_CLEAR(item);
return 0;
}
PyObject *
Config_get_multivar(Config *self, PyObject *args)
{
int err;
PyObject *list;
Py_ssize_t size;
const char *name = NULL;
const char *regex = NULL;
git_config_iterator *iter;
git_config_entry *entry;
if (!PyArg_ParseTuple(args, "s|s", &name, &regex))
return NULL;
list = PyList_New(0);
err = git_config_get_multivar(self->config, name, regex,
Config_get_multivar_fn_wrapper,
(void *)list);
if (err < 0) {
/* XXX The return value of git_config_get_multivar is not reliable,
* see https://github.com/libgit2/libgit2/pull/1712
* Once libgit2 0.20 is released, we will remove this test. */
if (err == GIT_ENOTFOUND && PyList_Size(list) != 0)
return list;
Py_CLEAR(list);
err = git_config_multivar_iterator_new(&iter, self->config, name, regex);
if (err < 0)
return Error_set(err);
while ((err = git_config_next(&entry, iter)) == 0) {
PyObject *item;
item = to_unicode(entry->value, NULL, NULL);
if (item == NULL) {
git_config_iterator_free(iter);
return NULL;
}
PyList_Append(list, item);
Py_CLEAR(item);
}
git_config_iterator_free(iter);
if (err == GIT_ITEROVER)
err = 0;
if (err < 0)
return Error_set(err);
return list;
}

View File

@ -43,7 +43,7 @@ extern PyTypeObject HunkType;
PyTypeObject PatchType;
PyObject*
wrap_diff(git_diff_list *diff, Repository *repo)
wrap_diff(git_diff *diff, Repository *repo)
{
Diff *py_diff;
@ -58,23 +58,24 @@ wrap_diff(git_diff_list *diff, Repository *repo)
}
PyObject*
diff_get_patch_byindex(git_diff_list* list, size_t idx)
diff_get_patch_byindex(git_diff* diff, size_t idx)
{
const git_diff_delta* delta;
const git_diff_range* range;
git_diff_patch* patch = NULL;
size_t i, j, hunk_amounts, lines_in_hunk, line_len, header_len, additions, deletions;
const char* line, *header;
char line_origin;
const git_diff_hunk *hunk;
const git_diff_line *line;
git_patch* patch = NULL;
size_t i, j, hunk_amounts, lines_in_hunk, additions, deletions;
int err;
Hunk *py_hunk = NULL;
Patch *py_patch = NULL;
PyObject *py_line_origin=NULL, *py_line=NULL;
err = git_diff_get_patch(&patch, &delta, list, idx);
err = git_patch_from_diff(&patch, diff, idx);
if (err < 0)
return Error_set(err);
delta = git_patch_get_delta(patch);
py_patch = PyObject_New(Patch, &PatchType);
if (py_patch != NULL) {
py_patch->old_file_path = delta->old_file.path;
@ -85,36 +86,34 @@ diff_get_patch_byindex(git_diff_list* list, size_t idx)
py_patch->old_oid = git_oid_allocfmt(&delta->old_file.oid);
py_patch->new_oid = git_oid_allocfmt(&delta->new_file.oid);
git_diff_patch_line_stats(NULL, &additions, &deletions, patch);
git_patch_line_stats(NULL, &additions, &deletions, patch);
py_patch->additions = additions;
py_patch->deletions = deletions;
hunk_amounts = git_diff_patch_num_hunks(patch);
hunk_amounts = git_patch_num_hunks(patch);
py_patch->hunks = PyList_New(hunk_amounts);
for (i=0; i < hunk_amounts; ++i) {
err = git_diff_patch_get_hunk(&range, &header, &header_len,
&lines_in_hunk, patch, i);
err = git_patch_get_hunk(&hunk, &lines_in_hunk, patch, i);
if (err < 0)
goto cleanup;
py_hunk = PyObject_New(Hunk, &HunkType);
if (py_hunk != NULL) {
py_hunk->old_start = range->old_start;
py_hunk->old_lines = range->old_lines;
py_hunk->new_start = range->new_start;
py_hunk->new_lines = range->new_lines;
py_hunk->old_start = hunk->old_start;
py_hunk->old_lines = hunk->old_lines;
py_hunk->new_start = hunk->new_start;
py_hunk->new_lines = hunk->new_lines;
py_hunk->lines = PyList_New(lines_in_hunk);
for (j=0; j < lines_in_hunk; ++j) {
err = git_diff_patch_get_line_in_hunk(&line_origin,
&line, &line_len, NULL, NULL, patch, i, j);
err = git_patch_get_line_in_hunk(&line, patch, i, j);
if (err < 0)
goto cleanup;
py_line_origin = to_unicode_n(&line_origin, 1, NULL, NULL);
py_line = to_unicode_n(line, line_len, NULL, NULL);
py_line_origin = to_unicode_n(&line->origin, 1, NULL, NULL);
py_line = to_unicode_n(line->content, line->content_len, NULL, NULL);
PyList_SetItem(py_hunk->lines, j,
Py_BuildValue("OO",
py_line_origin,
@ -132,7 +131,7 @@ diff_get_patch_byindex(git_diff_list* list, size_t idx)
}
cleanup:
git_diff_patch_free(patch);
git_patch_free(patch);
return (err < 0) ? Error_set(err) : (PyObject*) py_patch;
}
@ -283,8 +282,7 @@ PyDoc_STRVAR(Diff_patch__doc__, "Patch diff string.");
PyObject *
Diff_patch__get__(Diff *self)
{
const git_diff_delta* delta;
git_diff_patch* patch;
git_patch* patch;
char **strings = NULL;
char *buffer = NULL;
int err = GIT_ERROR;
@ -295,16 +293,16 @@ Diff_patch__get__(Diff *self)
MALLOC(strings, num * sizeof(char*), cleanup);
for (i = 0, len = 1; i < num ; ++i) {
err = git_diff_get_patch(&patch, &delta, self->list, i);
err = git_patch_from_diff(&patch, self->list, i);
if (err < 0)
goto cleanup;
err = git_diff_patch_to_str(&(strings[i]), patch);
err = git_patch_to_str(&(strings[i]), patch);
if (err < 0)
goto cleanup;
len += strlen(strings[i]);
git_diff_patch_free(patch);
git_patch_free(patch);
}
CALLOC(buffer, (len + 1), sizeof(char), cleanup);
@ -461,7 +459,7 @@ Diff_getitem(Diff *self, PyObject *value)
static void
Diff_dealloc(Diff *self)
{
git_diff_list_free(self->list);
git_diff_free(self->list);
Py_CLEAR(self->repo);
PyObject_Del(self);
}

View File

@ -41,6 +41,6 @@
PyObject* Diff_changes(Diff *self);
PyObject* Diff_patch(Diff *self);
PyObject* wrap_diff(git_diff_list *diff, Repository *repo);
PyObject* wrap_diff(git_diff *diff, Repository *repo);
#endif

View File

@ -135,7 +135,7 @@ PyObject *
Index_diff_to_workdir(Index *self, PyObject *args)
{
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff;
git_diff *diff;
int err;
if (!PyArg_ParseTuple(args, "|IHH", &opts.flags, &opts.context_lines,
@ -177,7 +177,7 @@ Index_diff_to_tree(Index *self, PyObject *args)
{
Repository *py_repo;
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff;
git_diff *diff;
int err;
Tree *py_tree = NULL;

View File

@ -99,8 +99,7 @@ init_repository(PyObject *self, PyObject *args) {
};
PyDoc_STRVAR(clone_repository__doc__,
"clone_repository(url, path, bare, remote_name, push_url,"
"fetch_spec, push_spec, checkout_branch)\n"
"clone_repository(url, path, bare, remote_name, checkout_branch)\n"
"\n"
"Clones a Git repository in the given url to the given path "
"with the specified options.\n"
@ -115,14 +114,6 @@ PyDoc_STRVAR(clone_repository__doc__,
" If 'bare' is not 0, then a bare git repository will be created.\n"
"remote_name\n"
" The name given to the 'origin' remote. The default is 'origin'.\n"
"push_url\n"
" URL to be used for pushing.\n"
"fetch_spec\n"
" The fetch specification to be used for fetching. None results in "
"the same behavior as GIT_REMOTE_DEFAULT_FETCH.\n"
"push_spec\n"
" The fetch specification to be used for pushing. None means use the "
"same spec as for 'fetch_spec'\n"
"checkout_branch\n"
" The name of the branch to checkout. None means use the remote's "
"HEAD.\n");
@ -133,22 +124,18 @@ clone_repository(PyObject *self, PyObject *args) {
git_repository *repo;
const char *url;
const char *path;
unsigned int bare;
const char *remote_name, *push_url, *fetch_spec;
const char *push_spec, *checkout_branch;
unsigned int bare, ignore_cert_errors;
const char *remote_name, *checkout_branch;
int err;
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
if (!PyArg_ParseTuple(args, "zzIzzzzz",
&url, &path, &bare, &remote_name, &push_url,
&fetch_spec, &push_spec, &checkout_branch))
if (!PyArg_ParseTuple(args, "zzIIzz",
&url, &path, &bare, &ignore_cert_errors, &remote_name, &checkout_branch))
return NULL;
opts.bare = bare;
opts.ignore_cert_errors = ignore_cert_errors;
opts.remote_name = remote_name;
opts.pushurl = push_url;
opts.fetch_spec = fetch_spec;
opts.push_spec = push_spec;
opts.checkout_branch = checkout_branch;
err = git_clone(&repo, url, path, &opts);
@ -392,8 +379,8 @@ moduleinit(PyObject* m)
ADD_CONSTANT_INT(m, GIT_DIFF_RECURSE_UNTRACKED_DIRS)
ADD_CONSTANT_INT(m, GIT_DIFF_RECURSE_UNTRACKED_DIRS)
ADD_CONSTANT_INT(m, GIT_DIFF_DISABLE_PATHSPEC_MATCH)
ADD_CONSTANT_INT(m, GIT_DIFF_DELTAS_ARE_ICASE)
ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_UNTRACKED_CONTENT)
ADD_CONSTANT_INT(m, GIT_DIFF_IGNORE_CASE)
ADD_CONSTANT_INT(m, GIT_DIFF_SHOW_UNTRACKED_CONTENT)
ADD_CONSTANT_INT(m, GIT_DIFF_SKIP_BINARY_CHECK)
ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_TYPECHANGE)
ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_TYPECHANGE_TREES)

View File

@ -309,13 +309,19 @@ PyDoc_STRVAR(Reference_log__doc__,
PyObject *
Reference_log(Reference *self)
{
int err;
RefLogIter *iter;
git_repository *repo;
CHECK_REFERENCE(self);
repo = git_reference_owner(self->reference);
iter = PyObject_New(RefLogIter, &RefLogIterType);
if (iter != NULL) {
git_reflog_read(&iter->reflog, self->reference);
err = git_reflog_read(&iter->reflog, repo, git_reference_name(self->reference));
if (err < 0)
return Error_set(err);
iter->size = git_reflog_entrycount(iter->reflog);
iter->i = 0;
}
@ -341,6 +347,7 @@ Reference_log_append(Reference *self, PyObject *args)
Signature *py_committer;
PyObject *py_message = NULL;
char *encoding = NULL;
git_repository *repo;
CHECK_REFERENCE(self);
@ -366,7 +373,8 @@ Reference_log_append(Reference *self, PyObject *args)
}
/* Go */
err = git_reflog_read(&reflog, self->reference);
repo = git_reference_owner(self->reference);
err = git_reflog_read(&reflog, repo, git_reference_name(self->reference));
if (err < 0) {
free((void *)message);
return NULL;

View File

@ -179,7 +179,7 @@ Remote_fetch(Remote *self, PyObject *args)
err = git_remote_connect(self->remote, GIT_DIRECTION_FETCH);
if (err == GIT_OK) {
err = git_remote_download(self->remote, NULL, NULL);
err = git_remote_download(self->remote);
if (err == GIT_OK) {
stats = git_remote_stats(self->remote);
py_stats = Py_BuildValue("{s:I,s:I,s:n}",

View File

@ -208,14 +208,14 @@ Repository_head_is_detached__get__(Repository *self)
}
PyDoc_STRVAR(Repository_head_is_orphaned__doc__,
"An orphan branch is one named from HEAD but which doesn't exist in the\n"
PyDoc_STRVAR(Repository_head_is_unborn__doc__,
"An unborn branch is one named from HEAD but which doesn't exist in the\n"
"refs namespace, because it doesn't have any commit to point to.");
PyObject *
Repository_head_is_orphaned__get__(Repository *self)
Repository_head_is_unborn__get__(Repository *self)
{
if (git_repository_head_orphan(self->repo) > 0)
if (git_repository_head_unborn(self->repo) > 0)
Py_RETURN_TRUE;
Py_RETURN_FALSE;
@ -430,9 +430,9 @@ Repository_write(Repository *self, PyObject *args)
if (err < 0)
return Error_set(err);
stream->write(stream, buffer, buflen);
err = stream->finalize_write(&oid, stream);
stream->free(stream);
git_odb_stream_write(stream, buffer, buflen);
err = git_odb_stream_finalize_write(&oid, stream);
git_odb_stream_free(stream);
return git_oid_to_python(&oid);
}
@ -1480,7 +1480,7 @@ PyGetSetDef Repository_getseters[] = {
GETTER(Repository, path),
GETSET(Repository, head),
GETTER(Repository, head_is_detached),
GETTER(Repository, head_is_orphaned),
GETTER(Repository, head_is_unborn),
GETTER(Repository, is_empty),
GETTER(Repository, is_bare),
GETTER(Repository, config),

View File

@ -290,7 +290,7 @@ PyObject *
Tree_diff_to_workdir(Tree *self, PyObject *args)
{
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff;
git_diff *diff;
Repository *py_repo;
int err;
@ -328,7 +328,7 @@ PyObject *
Tree_diff_to_index(Tree *self, PyObject *args, PyObject *kwds)
{
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff;
git_diff *diff;
Repository *py_repo;
int err;
@ -373,7 +373,7 @@ PyObject *
Tree_diff_to_tree(Tree *self, PyObject *args, PyObject *kwds)
{
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff;
git_diff *diff;
git_tree *from, *to, *tmp;
Repository *py_repo;
int err, swap = 0;

View File

@ -95,7 +95,7 @@ typedef struct {
/* git _diff */
SIMPLE_TYPE(Diff, git_diff_list, list)
SIMPLE_TYPE(Diff, git_diff, list)
typedef struct {
PyObject_HEAD

View File

@ -65,7 +65,7 @@ class RepositoryTest(utils.BareRepoTestCase):
head = self.repo.head
self.assertEqual(HEAD_SHA, head.target.hex)
self.assertEqual(type(head), Reference)
self.assertFalse(self.repo.head_is_orphaned)
self.assertFalse(self.repo.head_is_unborn)
self.assertFalse(self.repo.head_is_detached)
def test_read(self):
@ -294,7 +294,7 @@ class EmptyRepositoryTest(utils.EmptyRepoTestCase):
self.assertFalse(self.repo.is_bare)
def test_head(self):
self.assertTrue(self.repo.head_is_orphaned)
self.assertTrue(self.repo.head_is_unborn)
self.assertFalse(self.repo.head_is_detached)