From b7e906eee9d503fd6dee55fee5c7e7bc8e28978d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Wed, 30 Oct 2013 08:57:17 +0100 Subject: [PATCH] Adjust to libgit2 development branch This wraps the previous functionality, though there are some iterator changes we might still want to bring over. --- pygit2/__init__.py | 17 +++---------- src/config.c | 55 +++++++++++++++++------------------------ src/diff.c | 54 +++++++++++++++++++--------------------- src/diff.h | 2 +- src/index.c | 4 +-- src/pygit2.c | 29 ++++++---------------- src/reference.c | 12 +++++++-- src/remote.c | 2 +- src/repository.c | 16 ++++++------ src/tree.c | 6 ++--- src/types.h | 2 +- test/test_repository.py | 4 +-- 12 files changed, 87 insertions(+), 116 deletions(-) diff --git a/pygit2/__init__.py b/pygit2/__init__.py index e59d3c3..e2d5246 100644 --- a/pygit2/__init__.py +++ b/pygit2/__init__.py @@ -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) diff --git a/src/config.c b/src/config.c index dc9b44f..b1e7afd 100644 --- a/src/config.c +++ b/src/config.c @@ -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, ®ex)) return NULL; list = PyList_New(0); - err = git_config_get_multivar(self->config, name, regex, - Config_get_multivar_fn_wrapper, - (void *)list); + err = git_config_multivar_iterator_new(&iter, self->config, name, regex); + if (err < 0) + return Error_set(err); - 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; + while ((err = git_config_next(&entry, iter)) == 0) { + PyObject *item; - Py_CLEAR(list); - return Error_set(err); + 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; } diff --git a/src/diff.c b/src/diff.c index 3b5c4fe..01e6e7d 100644 --- a/src/diff.c +++ b/src/diff.c @@ -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); - if (err < 0) + 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); } diff --git a/src/diff.h b/src/diff.h index 75e6333..f32c930 100644 --- a/src/diff.h +++ b/src/diff.h @@ -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 diff --git a/src/index.c b/src/index.c index 3c73f21..bd7a763 100644 --- a/src/index.c +++ b/src/index.c @@ -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; diff --git a/src/pygit2.c b/src/pygit2.c index 20fd27a..85c146f 100644 --- a/src/pygit2.c +++ b/src/pygit2.c @@ -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) diff --git a/src/reference.c b/src/reference.c index 62ebbc6..70108af 100644 --- a/src/reference.c +++ b/src/reference.c @@ -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; diff --git a/src/remote.c b/src/remote.c index e482d8b..6b684ec 100644 --- a/src/remote.c +++ b/src/remote.c @@ -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}", diff --git a/src/repository.c b/src/repository.c index facc0ce..222fd23 100644 --- a/src/repository.c +++ b/src/repository.c @@ -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), diff --git a/src/tree.c b/src/tree.c index e0abbbd..7599d65 100644 --- a/src/tree.c +++ b/src/tree.c @@ -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; diff --git a/src/types.h b/src/types.h index 6c2136d..cbfa9aa 100644 --- a/src/types.h +++ b/src/types.h @@ -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 diff --git a/test/test_repository.py b/test/test_repository.py index ab0b22c..e783f80 100644 --- a/test/test_repository.py +++ b/test/test_repository.py @@ -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)