From 7a606b9b1c87788e60f3ce3822533937cf204263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 19 Jan 2014 01:27:26 +0100 Subject: [PATCH 01/13] Adjust to libgit2 dup changes --- src/blame.c | 14 ++++++++++---- src/reference.c | 3 +-- src/tree.c | 20 ++++++++++---------- src/treebuilder.c | 10 +++++----- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/blame.c b/src/blame.c index 80b82089a..b238f050a 100644 --- a/src/blame.c +++ b/src/blame.c @@ -69,14 +69,20 @@ wrap_blame_hunk(const git_blame_hunk *hunk, Blame *blame) py_hunk->lines_in_hunk = hunk->lines_in_hunk; py_hunk->final_commit_id = git_oid_allocfmt(&hunk->final_commit_id); py_hunk->final_start_line_number = hunk->final_start_line_number; - py_hunk->final_signature = hunk->final_signature != NULL ? - git_signature_dup(hunk->final_signature) : NULL; + + py_hunk->final_signature = NULL; + if (hunk->final_signature) + git_signature_dup(&py_hunk->final_signature, hunk->final_signature); + py_hunk->orig_commit_id = git_oid_allocfmt(&hunk->orig_commit_id); py_hunk->orig_path = hunk->orig_path != NULL ? strdup(hunk->orig_path) : NULL; py_hunk->orig_start_line_number = hunk->orig_start_line_number; - py_hunk->orig_signature = hunk->orig_signature != NULL ? - git_signature_dup(hunk->orig_signature) : NULL; + + py_hunk->orig_signature = NULL; + if (hunk->orig_signature) + git_signature_dup(&py_hunk->orig_signature, hunk->orig_signature); + py_hunk->boundary = hunk->boundary; } diff --git a/src/reference.c b/src/reference.c index e597e353a..1c78d4199 100644 --- a/src/reference.c +++ b/src/reference.c @@ -62,8 +62,7 @@ RefLogIter_iternext(RefLogIter *self) py_entry->oid_old = git_oid_allocfmt(git_reflog_entry_id_old(entry)); py_entry->oid_new = git_oid_allocfmt(git_reflog_entry_id_new(entry)); py_entry->message = strdup(git_reflog_entry_message(entry)); - py_entry->signature = git_signature_dup( - git_reflog_entry_committer(entry)); + git_signature_dup(&py_entry->signature, git_reflog_entry_committer(entry)); ++(self->i); diff --git a/src/tree.c b/src/tree.c index d1968faed..b72d57858 100644 --- a/src/tree.c +++ b/src/tree.c @@ -284,20 +284,20 @@ TreeEntry * Tree_getitem_by_index(Tree *self, PyObject *py_index) { int index; - const git_tree_entry *entry; + const git_tree_entry *entry_src; + git_tree_entry *entry; index = Tree_fix_index(self, py_index); if (PyErr_Occurred()) return NULL; - entry = git_tree_entry_byindex(self->tree, index); - if (!entry) { + entry_src = git_tree_entry_byindex(self->tree, index); + if (!entry_src) { PyErr_SetObject(PyExc_IndexError, py_index); return NULL; } - entry = git_tree_entry_dup(entry); - if (entry == NULL) { + if (git_tree_entry_dup(&entry, entry_src) < 0) { PyErr_SetNone(PyExc_MemoryError); return NULL; } @@ -550,16 +550,16 @@ TreeIter_dealloc(TreeIter *self) TreeEntry * TreeIter_iternext(TreeIter *self) { - const git_tree_entry *entry; + const git_tree_entry *entry_src; + git_tree_entry *entry; - entry = git_tree_entry_byindex(self->owner->tree, self->i); - if (!entry) + entry_src = git_tree_entry_byindex(self->owner->tree, self->i); + if (!entry_src) return NULL; self->i += 1; - entry = git_tree_entry_dup(entry); - if (entry == NULL) { + if (git_tree_entry_dup(&entry, entry_src) < 0) { PyErr_SetNone(PyExc_MemoryError); return NULL; } diff --git a/src/treebuilder.c b/src/treebuilder.c index 8354b1b5e..5957040ce 100644 --- a/src/treebuilder.c +++ b/src/treebuilder.c @@ -105,19 +105,19 @@ PyObject * TreeBuilder_get(TreeBuilder *self, PyObject *py_filename) { char *filename; - const git_tree_entry *entry; + const git_tree_entry *entry_src; + git_tree_entry *entry; filename = py_path_to_c_str(py_filename); if (filename == NULL) return NULL; - entry = git_treebuilder_get(self->bld, filename); + entry_src = git_treebuilder_get(self->bld, filename); free(filename); - if (entry == NULL) + if (entry_src == NULL) Py_RETURN_NONE; - entry = git_tree_entry_dup(entry); - if (entry == NULL) { + if (git_tree_entry_dup(&entry, entry_src) < 0) { PyErr_SetNone(PyExc_MemoryError); return NULL; } From 423b912fae0e17bd50b6989a354048b03a28a16b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 19 Jan 2014 01:29:03 +0100 Subject: [PATCH 02/13] Adjust to reference creation signatures --- src/branch.c | 2 +- src/reference.c | 6 +++--- src/remote.c | 4 ++-- src/repository.c | 10 +++++----- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/branch.c b/src/branch.c index bcf763677..32879f346 100644 --- a/src/branch.c +++ b/src/branch.c @@ -101,7 +101,7 @@ Branch_rename(Branch *self, PyObject *args) if (!PyArg_ParseTuple(args, "s|i", &c_name, &force)) return NULL; - err = git_branch_move(&c_out, self->reference, c_name, force); + err = git_branch_move(&c_out, self->reference, c_name, force, NULL, NULL); if (err == GIT_OK) return wrap_branch(c_out, self->repo); else diff --git a/src/reference.c b/src/reference.c index 1c78d4199..2c5e0ff52 100644 --- a/src/reference.c +++ b/src/reference.c @@ -159,7 +159,7 @@ Reference_rename(Reference *self, PyObject *py_name) return NULL; /* Rename */ - err = git_reference_rename(&new_reference, self->reference, c_name, 0); + err = git_reference_rename(&new_reference, self->reference, c_name, 0, NULL, NULL); git_reference_free(self->reference); free(c_name); if (err < 0) @@ -239,7 +239,7 @@ Reference_target__set__(Reference *self, PyObject *py_target) if (err < 0) return err; - err = git_reference_set_target(&new_ref, self->reference, &oid); + err = git_reference_set_target(&new_ref, self->reference, &oid, NULL, NULL); if (err < 0) goto error; @@ -253,7 +253,7 @@ Reference_target__set__(Reference *self, PyObject *py_target) if (c_name == NULL) return -1; - err = git_reference_symbolic_set_target(&new_ref, self->reference, c_name); + err = git_reference_symbolic_set_target(&new_ref, self->reference, c_name, NULL, NULL); free(c_name); if (err < 0) goto error; diff --git a/src/remote.c b/src/remote.c index dee9b5a76..deb832d6c 100644 --- a/src/remote.c +++ b/src/remote.c @@ -467,7 +467,7 @@ Remote_fetch(Remote *self, PyObject *args) int err; PyErr_Clear(); - err = git_remote_fetch(self->remote); + err = git_remote_fetch(self->remote, NULL, NULL); /* * XXX: We should be checking for GIT_EUSER, but on v0.20, this does not * make it all the way to us for update_tips @@ -558,7 +558,7 @@ Remote_push(Remote *self, PyObject *args) return NULL; } - err = git_push_update_tips(push); + err = git_push_update_tips(push, NULL, NULL); if (err < 0) goto error; diff --git a/src/repository.c b/src/repository.c index bb2a11b96..738627fd3 100644 --- a/src/repository.c +++ b/src/repository.c @@ -192,7 +192,7 @@ Repository_head__set__(Repository *self, PyObject *py_refname) if (refname == NULL) return -1; - err = git_repository_set_head(self->repo, refname); + err = git_repository_set_head(self->repo, refname, NULL, NULL); Py_DECREF(trefname); if (err < 0) { Error_set_str(err, refname); @@ -929,7 +929,7 @@ Repository_create_branch(Repository *self, PyObject *args) if (!PyArg_ParseTuple(args, "sO!|i", &c_name, &CommitType, &py_commit, &force)) return NULL; - err = git_branch_create(&c_reference, self->repo, c_name, py_commit->commit, force); + err = git_branch_create(&c_reference, self->repo, c_name, py_commit->commit, force, NULL, NULL); if (err < 0) return Error_set(err); @@ -1096,7 +1096,7 @@ Repository_create_reference_direct(Repository *self, PyObject *args, if (err < 0) return NULL; - err = git_reference_create(&c_reference, self->repo, c_name, &oid, force); + err = git_reference_create(&c_reference, self->repo, c_name, &oid, force, NULL, NULL); if (err < 0) return Error_set(err); @@ -1130,7 +1130,7 @@ Repository_create_reference_symbolic(Repository *self, PyObject *args, return NULL; err = git_reference_symbolic_create(&c_reference, self->repo, c_name, - c_target, force); + c_target, force, NULL, NULL); if (err < 0) return Error_set(err); @@ -1607,7 +1607,7 @@ Repository_reset(Repository *self, PyObject* args) err = git_object_lookup_prefix(&target, self->repo, &oid, len, GIT_OBJ_ANY); - err = err < 0 ? err : git_reset(self->repo, target, reset_type); + err = err < 0 ? err : git_reset(self->repo, target, reset_type, NULL, NULL); git_object_free(target); if (err < 0) return Error_set_oid(err, &oid, len); From 9cec62d2e1faeb0bb7e3e72af08335e3b08f634f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 19 Jan 2014 02:01:50 +0100 Subject: [PATCH 03/13] Blame: orig_ is now filled --- test/test_blame.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/test/test_blame.py b/test/test_blame.py index dbe9e6bf0..cbdba9c6a 100644 --- a/test/test_blame.py +++ b/test/test_blame.py @@ -65,11 +65,10 @@ def test_blame_index(self): self.assertEqual(HUNKS[i][0], hunk.final_commit_id) self.assertEqual(HUNKS[i][1], hunk.final_start_line_number) self.assertEqualSignature(HUNKS[i][2], hunk.final_committer) - self.assertEqual(hunk.orig_commit_id, - '0000000000000000000000000000000000000000') + self.assertEqual(HUNKS[i][0], hunk.orig_commit_id) self.assertEqual(hunk.orig_path, PATH) self.assertEqual(HUNKS[i][1], hunk.orig_start_line_number) - self.assertTrue(hunk.orig_committer is None) + self.assertEqualSignature(HUNKS[i][2], hunk.orig_committer) self.assertEqual(HUNKS[i][3], hunk.boundary) def test_blame_with_invalid_index(self): @@ -93,11 +92,10 @@ def test_blame_for_line(self): self.assertEqual(HUNKS[i][0], hunk.final_commit_id) self.assertEqual(HUNKS[i][1], hunk.final_start_line_number) self.assertEqualSignature(HUNKS[i][2], hunk.final_committer) - self.assertEqual(hunk.orig_commit_id, - '0000000000000000000000000000000000000000') + self.assertEqual(HUNKS[i][0], hunk.orig_commit_id) self.assertEqual(hunk.orig_path, PATH) self.assertEqual(HUNKS[i][1], hunk.orig_start_line_number) - self.assertTrue(hunk.orig_committer is None) + self.assertEqualSignature(HUNKS[i][2], hunk.orig_committer) self.assertEqual(HUNKS[i][3], hunk.boundary) def test_blame_with_invalid_line(self): @@ -131,11 +129,10 @@ def test_blame_newest(self): self.assertEqual(HUNKS[i][0], hunk.final_commit_id) self.assertEqual(HUNKS[i][1], hunk.final_start_line_number) self.assertEqualSignature(HUNKS[i][2], hunk.final_committer) - self.assertEqual(hunk.orig_commit_id, - '0000000000000000000000000000000000000000') + self.assertEqual(HUNKS[i][0], hunk.orig_commit_id) self.assertEqual(hunk.orig_path, PATH) self.assertEqual(HUNKS[i][1], hunk.orig_start_line_number) - self.assertTrue(hunk.orig_committer is None) + self.assertEqualSignature(HUNKS[i][2], hunk.orig_committer) self.assertEqual(HUNKS[i][3], hunk.boundary) if __name__ == '__main__': From dd6fc972dd3b47668e3352af202cb33b76544a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 2 Feb 2014 19:40:48 +0100 Subject: [PATCH 04/13] Adjust to the git_buf changes We no longer need the max-path define, so we can get rid of that and the pypy checking. --- src/branch.c | 47 +++++++++-------------------------------------- src/config.c | 20 ++++++++++++++------ src/diff.c | 20 ++++++-------------- src/pygit2.c | 22 ++++++++-------------- src/refspec.c | 46 ++++++++++++---------------------------------- 5 files changed, 49 insertions(+), 106 deletions(-) diff --git a/src/branch.c b/src/branch.c index 32879f346..39ddd675d 100644 --- a/src/branch.c +++ b/src/branch.c @@ -135,34 +135,19 @@ PyObject * Branch_remote_name__get__(Branch *self) { int err; + git_buf name = {NULL}; const char *branch_name; - char *c_name = NULL; PyObject *py_name; CHECK_REFERENCE(self); branch_name = git_reference_name(self->reference); - /* Get the length of the remote name */ - err = git_branch_remote_name(NULL, 0, self->repo->repo, branch_name); + err = git_branch_remote_name(&name, self->repo->repo, branch_name); if (err < GIT_OK) return Error_set(err); - /* Get the actual remote name */ - c_name = calloc(err, sizeof(char)); - if (c_name == NULL) - return PyErr_NoMemory(); - - err = git_branch_remote_name(c_name, - err * sizeof(char), - self->repo->repo, - branch_name); - if (err < GIT_OK) { - free(c_name); - return Error_set(err); - } - - py_name = to_unicode_n(c_name, err - 1, NULL, NULL); - free(c_name); + py_name = to_unicode(name.ptr, NULL, NULL); + git_buf_free(&name); return py_name; } @@ -227,34 +212,20 @@ PyObject * Branch_upstream_name__get__(Branch *self) { int err; + git_buf name = {NULL}; const char *branch_name; - char *c_name = NULL; PyObject *py_name; CHECK_REFERENCE(self); branch_name = git_reference_name(self->reference); - /* Get the length of the upstream name */ - err = git_branch_upstream_name(NULL, 0, self->repo->repo, branch_name); - if (err < GIT_OK) - return Error_set(err); - - /* Get the actual upstream name */ - c_name = calloc(err, sizeof(char)); - if (c_name == NULL) - return PyErr_NoMemory(); - err = git_branch_upstream_name(c_name, - err * sizeof(char), - self->repo->repo, - branch_name); - if (err < GIT_OK) { - free(c_name); + err = git_branch_upstream_name(&name, self->repo->repo, branch_name); + if (err < GIT_OK) return Error_set(err); - } - py_name = to_unicode_n(c_name, err - 1, NULL, NULL); - free(c_name); + py_name = to_unicode(name.ptr, NULL, NULL); + git_buf_free(&name); return py_name; } diff --git a/src/config.c b/src/config.c index 9b2625d6a..393fded93 100644 --- a/src/config.c +++ b/src/config.c @@ -103,10 +103,11 @@ PyDoc_STRVAR(Config_get_global_config__doc__, PyObject * Config_get_global_config(void) { - char path[GIT_PATH_MAX]; + git_buf path = {NULL}; + PyObject *py_config; int err; - err = git_config_find_global(path, GIT_PATH_MAX); + err = git_config_find_global(&path); if (err < 0) { if (err == GIT_ENOTFOUND) { PyErr_SetString(PyExc_IOError, "Global config file not found."); @@ -116,7 +117,10 @@ Config_get_global_config(void) return Error_set(err); } - return wrap_config(path); + py_config = wrap_config(path.ptr); + + git_buf_free(&path); + return py_config; } @@ -128,10 +132,11 @@ PyDoc_STRVAR(Config_get_system_config__doc__, PyObject * Config_get_system_config(void) { - char path[GIT_PATH_MAX]; + git_buf path = {NULL}; + PyObject *py_config; int err; - err = git_config_find_system(path, GIT_PATH_MAX); + err = git_config_find_system(&path); if (err < 0) { if (err == GIT_ENOTFOUND) { PyErr_SetString(PyExc_IOError, "System config file not found."); @@ -140,7 +145,10 @@ Config_get_system_config(void) return Error_set(err); } - return wrap_config(path); + py_config = wrap_config(path.ptr); + + git_buf_free(&path); + return py_config; } diff --git a/src/diff.c b/src/diff.c index adea3cdd8..da0887406 100644 --- a/src/diff.c +++ b/src/diff.c @@ -292,8 +292,7 @@ PyObject * Diff_patch__get__(Diff *self) { git_patch* patch; - char **strings = NULL; - char *buffer = NULL; + git_buf buf = {NULL}; int err = GIT_ERROR; size_t i, len, num; PyObject *py_patch = NULL; @@ -301,32 +300,25 @@ Diff_patch__get__(Diff *self) num = git_diff_num_deltas(self->list); if (num == 0) Py_RETURN_NONE; - MALLOC(strings, num * sizeof(char*), cleanup); for (i = 0, len = 1; i < num ; ++i) { err = git_patch_from_diff(&patch, self->list, i); if (err < 0) goto cleanup; - err = git_patch_to_str(&(strings[i]), patch); + /* This appends to the current buf, so we can simply keep passing it */ + err = git_patch_to_buf(&buf, patch); if (err < 0) goto cleanup; - len += strlen(strings[i]); git_patch_free(patch); } - CALLOC(buffer, (len + 1), sizeof(char), cleanup); - for (i = 0; i < num; ++i) { - strcat(buffer, strings[i]); - free(strings[i]); - } - free(strings); - - py_patch = to_unicode(buffer, NULL, NULL); - free(buffer); + py_patch = to_unicode(buf.ptr, NULL, NULL); + git_buf_free(&buf); cleanup: + git_buf_free(&buf); return (err < 0) ? Error_set(err) : py_patch; } diff --git a/src/pygit2.c b/src/pygit2.c index bda9545ec..2e80cc5b1 100644 --- a/src/pygit2.c +++ b/src/pygit2.c @@ -28,11 +28,6 @@ #define PY_SSIZE_T_CLEAN #include -/* Pypy does not provide this header */ -#ifndef PYPY_VERSION -# include -#endif - #include #include "error.h" #include "types.h" @@ -41,11 +36,6 @@ #include "oid.h" #include "options.h" -/* FIXME: This is for pypy */ -#ifndef MAXPATHLEN -# define MAXPATHLEN 1024 -#endif - extern PyObject *GitError; extern PyTypeObject RepositoryType; @@ -187,21 +177,25 @@ PyDoc_STRVAR(discover_repository__doc__, PyObject * discover_repository(PyObject *self, PyObject *args) { + git_buf repo_path = {NULL}; const char *path; + PyObject *py_repo_path; int across_fs = 0; const char *ceiling_dirs = NULL; - char repo_path[MAXPATHLEN]; int err; if (!PyArg_ParseTuple(args, "s|Is", &path, &across_fs, &ceiling_dirs)) return NULL; - err = git_repository_discover(repo_path, sizeof(repo_path), - path, across_fs, ceiling_dirs); + memset(&repo_path, 0, sizeof(git_buf)); + err = git_repository_discover(&repo_path, path, across_fs, ceiling_dirs); if (err < 0) return Error_set_str(err, path); - return to_path(repo_path); + py_repo_path = to_path(repo_path.ptr); + git_buf_free(&repo_path); + + return py_repo_path; }; PyDoc_STRVAR(hashfile__doc__, diff --git a/src/refspec.c b/src/refspec.c index 3053fe60b..008aa6648 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -155,35 +155,24 @@ PyDoc_STRVAR(Refspec_transform__doc__, PyObject * Refspec_transform(Refspec *self, PyObject *py_str) { + git_buf trans = {NULL}; const char *str; - char *trans; - int err, len, alen; + int err; PyObject *py_trans, *tstr; str = py_str_borrow_c_str(&tstr, py_str, NULL); - alen = len = strlen(str); - - do { - alen *= alen; - trans = malloc(alen); - if (!trans) { - Py_DECREF(tstr); - return PyErr_NoMemory(); - } - - err = git_refspec_transform(trans, alen, self->refspec, str); - } while(err == GIT_EBUFS); + + err = git_refspec_transform(&trans, self->refspec, str); Py_DECREF(tstr); if (err < 0) { - free(trans); Error_set(err); return NULL; } - py_trans = to_unicode(trans, NULL, NULL); + py_trans = to_unicode(trans.ptr, NULL, NULL); - free(trans); + git_buf_free(&trans); return py_trans; } @@ -196,35 +185,24 @@ PyDoc_STRVAR(Refspec_rtransform__doc__, PyObject * Refspec_rtransform(Refspec *self, PyObject *py_str) { + git_buf trans = {NULL}; const char *str; - char *trans; - int err, len, alen; + int err; PyObject *py_trans, *tstr; str = py_str_borrow_c_str(&tstr, py_str, NULL); - alen = len = strlen(str); - - do { - alen *= alen; - trans = malloc(alen); - if (!trans) { - Py_DECREF(tstr); - return PyErr_NoMemory(); - } - - err = git_refspec_rtransform(trans, alen, self->refspec, str); - } while(err == GIT_EBUFS); + + err = git_refspec_rtransform(&trans, self->refspec, str); Py_DECREF(tstr); if (err < 0) { - free(trans); Error_set(err); return NULL; } - py_trans = to_unicode(trans, NULL, NULL); + py_trans = to_unicode(trans.ptr, NULL, NULL); - free(trans); + git_buf_free(&trans); return py_trans; } From e5f6798f67cb7de2edbfbfc0b20571d6979c7650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 2 Feb 2014 20:28:23 +0100 Subject: [PATCH 05/13] Adjust to oid -> id renaming --- docs/diff.rst | 4 ++-- docs/merge.rst | 8 ++++---- docs/objects.rst | 24 ++++++++++++------------ docs/references.rst | 6 +++--- docs/working-copy.rst | 6 +++--- src/diff.c | 12 ++++++------ src/index.c | 16 ++++++++-------- src/mergeresult.c | 12 ++++++------ src/note.c | 8 ++++---- src/repository.c | 6 +++--- src/types.h | 4 ++-- test/test_diff.py | 6 +++--- test/test_index.py | 8 ++++---- test/test_note.py | 4 ++-- test/test_repository.py | 14 +++++++------- 15 files changed, 69 insertions(+), 69 deletions(-) diff --git a/docs/diff.rst b/docs/diff.rst index 09fc9da21..dc7bf4dc0 100644 --- a/docs/diff.rst +++ b/docs/diff.rst @@ -50,8 +50,8 @@ Attributes: .. autoattribute:: pygit2.Patch.old_file_path .. autoattribute:: pygit2.Patch.new_file_path -.. autoattribute:: pygit2.Patch.old_oid -.. autoattribute:: pygit2.Patch.new_oid +.. autoattribute:: pygit2.Patch.old_id +.. autoattribute:: pygit2.Patch.new_id .. autoattribute:: pygit2.Patch.status .. autoattribute:: pygit2.Patch.similarity .. autoattribute:: pygit2.Patch.hunks diff --git a/docs/merge.rst b/docs/merge.rst index 4d98590aa..47984a868 100644 --- a/docs/merge.rst +++ b/docs/merge.rst @@ -22,8 +22,8 @@ merge with the default ones defined in GIT_MERGE_OPTS_INIT libgit2 constant. Example:: >>> branch_head_hex = '5ebeeebb320790caf276b9fc8b24546d63316533' - >>> branch_oid = self.repo.get(branch_head_hex).id - >>> merge_result = self.repo.merge(branch_oid) + >>> branch_id = self.repo.get(branch_head_hex).id + >>> merge_result = self.repo.merge(branch_id) The MergeResult object ====================== @@ -33,5 +33,5 @@ Represents the result of a merge and contains these fields: - is_uptodate: bool, if there wasn't any merge because the repo was already up to date - is_fastforward: bool, whether the merge was fastforward or not -- fastforward_oid: Oid, in the case it was a fastforward, this is the - forwarded Oid. +- fastforward_id: Oid, in the case it was a fastforward, this is the + forwarded id. diff --git a/docs/objects.rst b/docs/objects.rst index 3583c17ec..b9d038bbc 100644 --- a/docs/objects.rst +++ b/docs/objects.rst @@ -14,14 +14,14 @@ type. Object lookup ================= -In the previous chapter we learnt about Object IDs. With an oid we can ask the +In the previous chapter we learnt about Object IDs. With an Oid we can ask the repository to get the associated object. To do that the ``Repository`` class implementes a subset of the mapping interface. .. automethod:: pygit2.Repository.get - Return the Git object for the given *oid*, returns the *default* value if - there's no object in the repository with that oid. The oid can be an Oid + Return the Git object for the given *id*, returns the *default* value if + there's no object in the repository with that id. The id can be an Oid object, or an hexadecimal string. Example:: @@ -32,16 +32,16 @@ implementes a subset of the mapping interface. >>> obj <_pygit2.Commit object at 0x7ff27a6b60f0> -.. method:: Repository.__getitem__(oid) +.. method:: Repository.__getitem__(id) - Return the Git object for the given oid, raise ``KeyError`` if there's no - object in the repository with that oid. The oid can be an Oid object, or + Return the Git object for the given id, raise ``KeyError`` if there's no + object in the repository with that id. The id can be an Oid object, or an hexadecimal string. -.. method:: Repository.__contains__(oid) +.. method:: Repository.__contains__(id) - Returns True if there is an object in the Repository with that oid, False - if there is not. The oid can be an Oid object, or an hexadecimal string. + Returns True if there is an object in the Repository with that id, False + if there is not. The id can be an Oid object, or an hexadecimal string. The Object base type @@ -125,15 +125,15 @@ them to the Git object database: Example: - >>> oid = repo.create_blob('foo bar') # Creates blob from bytes string - >>> blob = repo[oid] + >>> id = repo.create_blob('foo bar') # Creates blob from bytes string + >>> blob = repo[id] >>> blob.data 'foo bar' .. automethod:: pygit2.Repository.create_blob_fromworkdir .. automethod:: pygit2.Repository.create_blob_fromdisk -There are also some functions to calculate the oid for a byte string without +There are also some functions to calculate the id for a byte string without creating the blob object: .. autofunction:: pygit2.hash diff --git a/docs/references.rst b/docs/references.rst index 363e3eebe..049fa8122 100644 --- a/docs/references.rst +++ b/docs/references.rst @@ -92,8 +92,8 @@ Example:: >>> for entry in head.log(): ... print(entry.message) -.. autoattribute:: pygit2.RefLogEntry.oid_new -.. autoattribute:: pygit2.RefLogEntry.oid_old +.. autoattribute:: pygit2.RefLogEntry.id_new +.. autoattribute:: pygit2.RefLogEntry.id_old .. autoattribute:: pygit2.RefLogEntry.message .. autoattribute:: pygit2.RefLogEntry.committer @@ -109,6 +109,6 @@ The Note type -------------------- .. autoattribute:: pygit2.Note.annotated_id -.. autoattribute:: pygit2.Note.oid +.. autoattribute:: pygit2.Note.id .. autoattribute:: pygit2.Note.message .. automethod:: pygit2.Note.remove diff --git a/docs/working-copy.rst b/docs/working-copy.rst index 76bcada87..cc1853d1d 100644 --- a/docs/working-copy.rst +++ b/docs/working-copy.rst @@ -8,8 +8,8 @@ Index read:: >>> index = repo.index >>> index.read() - >>> oid = index['path/to/file'].id # from path to object id - >>> blob = repo[oid] # from object id to object + >>> id = index['path/to/file'].id # from path to object id + >>> blob = repo[id] # from object id to object Iterate over all entries of the index:: @@ -43,7 +43,7 @@ The Index type The IndexEntry type -------------------- -.. autoattribute:: pygit2.IndexEntry.oid +.. autoattribute:: pygit2.IndexEntry.id .. autoattribute:: pygit2.IndexEntry.hex .. autoattribute:: pygit2.IndexEntry.path .. autoattribute:: pygit2.IndexEntry.mode diff --git a/src/diff.c b/src/diff.c index da0887406..3aeddeb85 100644 --- a/src/diff.c +++ b/src/diff.c @@ -80,8 +80,8 @@ wrap_patch(git_patch *patch) py_patch->status = git_diff_status_char(delta->status); py_patch->similarity = delta->similarity; py_patch->flags = delta->flags; - py_patch->old_oid = git_oid_allocfmt(&delta->old_file.oid); - py_patch->new_oid = git_oid_allocfmt(&delta->new_file.oid); + py_patch->old_id = git_oid_allocfmt(&delta->old_file.id); + py_patch->new_id = git_oid_allocfmt(&delta->new_file.id); git_patch_line_stats(NULL, &additions, &deletions, patch); py_patch->additions = additions; @@ -149,8 +149,8 @@ static void Patch_dealloc(Patch *self) { Py_CLEAR(self->hunks); - free(self->old_oid); - free(self->new_oid); + free(self->old_id); + free(self->new_id); /* We do not have to free old_file_path and new_file_path, they will * be freed by git_diff_list_free in Diff_dealloc */ PyObject_Del(self); @@ -159,8 +159,8 @@ Patch_dealloc(Patch *self) PyMemberDef Patch_members[] = { MEMBER(Patch, old_file_path, T_STRING, "old file path"), MEMBER(Patch, new_file_path, T_STRING, "new file path"), - MEMBER(Patch, old_oid, T_STRING, "old oid"), - MEMBER(Patch, new_oid, T_STRING, "new oid"), + MEMBER(Patch, old_id, T_STRING, "old oid"), + MEMBER(Patch, new_id, T_STRING, "new oid"), MEMBER(Patch, status, T_CHAR, "status"), MEMBER(Patch, similarity, T_INT, "similarity"), MEMBER(Patch, hunks, T_OBJECT, "hunks"), diff --git a/src/index.c b/src/index.c index 726974986..1ae3a1bdd 100644 --- a/src/index.c +++ b/src/index.c @@ -628,7 +628,7 @@ IndexEntry_init(IndexEntry *self, PyObject *args, PyObject *kwds) return -1; if (id) - git_oid_cpy(&self->entry.oid, &id->oid); + git_oid_cpy(&self->entry.id, &id->oid); if (mode) self->entry.mode = mode; @@ -689,18 +689,18 @@ IndexEntry_path__set__(IndexEntry *self, PyObject *py_path) return 0; } -PyDoc_STRVAR(IndexEntry_oid__doc__, "Object id."); +PyDoc_STRVAR(IndexEntry_id__doc__, "Object id."); PyObject * -IndexEntry_oid__get__(IndexEntry *self) +IndexEntry_id__get__(IndexEntry *self) { - return git_oid_to_python(&self->entry.oid); + return git_oid_to_python(&self->entry.id); } int -IndexEntry_oid__set__(IndexEntry *self, PyObject *py_id) +IndexEntry_id__set__(IndexEntry *self, PyObject *py_id) { - if (!py_oid_to_git_oid(py_id, &self->entry.oid)) + if (!py_oid_to_git_oid(py_id, &self->entry.id)) return -1; return 0; @@ -711,13 +711,13 @@ PyDoc_STRVAR(IndexEntry_hex__doc__, "Hex id."); PyObject * IndexEntry_hex__get__(IndexEntry *self) { - return git_oid_to_py_str(&self->entry.oid); + return git_oid_to_py_str(&self->entry.id); } PyGetSetDef IndexEntry_getseters[] = { GETSET(IndexEntry, mode), GETSET(IndexEntry, path), - GETSET(IndexEntry, oid), + GETSET(IndexEntry, id), GETTER(IndexEntry, hex), {NULL}, }; diff --git a/src/mergeresult.c b/src/mergeresult.c index 345e56ee6..4579e4b02 100644 --- a/src/mergeresult.c +++ b/src/mergeresult.c @@ -80,15 +80,15 @@ MergeResult_is_fastforward__get__(MergeResult *self) Py_RETURN_FALSE; } -PyDoc_STRVAR(MergeResult_fastforward_oid__doc__, "Fastforward Oid"); +PyDoc_STRVAR(MergeResult_fastforward_id__doc__, "Fastforward Oid"); PyObject * -MergeResult_fastforward_oid__get__(MergeResult *self) +MergeResult_fastforward_id__get__(MergeResult *self) { if (git_merge_result_is_fastforward(self->result)) { - git_oid fastforward_oid; - git_merge_result_fastforward_oid(&fastforward_oid, self->result); - return git_oid_to_python((const git_oid *)&fastforward_oid); + git_oid fastforward_id; + git_merge_result_fastforward_id(&fastforward_id, self->result); + return git_oid_to_python((const git_oid *)&fastforward_id); } else Py_RETURN_NONE; } @@ -96,7 +96,7 @@ MergeResult_fastforward_oid__get__(MergeResult *self) PyGetSetDef MergeResult_getseters[] = { GETTER(MergeResult, is_uptodate), GETTER(MergeResult, is_fastforward), - GETTER(MergeResult, fastforward_oid), + GETTER(MergeResult, fastforward_id), {NULL}, }; diff --git a/src/note.c b/src/note.c index e14e30862..9762ef61e 100644 --- a/src/note.c +++ b/src/note.c @@ -66,13 +66,13 @@ Note_remove(Note *self, PyObject* args) } -PyDoc_STRVAR(Note_oid__doc__, +PyDoc_STRVAR(Note_id__doc__, "Gets the id of the blob containing the note message\n"); PyObject * -Note_oid__get__(Note *self) +Note_id__get__(Note *self) { - return git_oid_to_python(git_note_oid(self->note)); + return git_oid_to_python(git_note_id(self->note)); } @@ -108,7 +108,7 @@ PyMemberDef Note_members[] = { PyGetSetDef Note_getseters[] = { GETTER(Note, message), - GETTER(Note, oid), + GETTER(Note, id), {NULL} }; diff --git a/src/repository.c b/src/repository.c index 738627fd3..53f9649db 100644 --- a/src/repository.c +++ b/src/repository.c @@ -588,9 +588,9 @@ Repository_merge_base(Repository *self, PyObject *args) } PyDoc_STRVAR(Repository_merge__doc__, - "merge(oid) -> MergeResult\n" + "merge(id) -> MergeResult\n" "\n" - "Merges the given oid and returns the MergeResult.\n" + "Merges the given id and returns the MergeResult.\n" "\n" "If the merge is fastforward the MergeResult will contain the new\n" "fastforward oid.\n" @@ -614,7 +614,7 @@ Repository_merge(Repository *self, PyObject *py_oid) if (len == 0) return NULL; - err = git_merge_head_from_oid(&oid_merge_head, self->repo, &oid); + err = git_merge_head_from_id(&oid_merge_head, self->repo, &oid); if (err < 0) return Error_set(err); diff --git a/src/types.h b/src/types.h index cfd00092c..f1273990f 100644 --- a/src/types.h +++ b/src/types.h @@ -114,8 +114,8 @@ typedef struct { PyObject* hunks; const char * old_file_path; const char * new_file_path; - char* old_oid; - char* new_oid; + char* old_id; + char* new_id; char status; unsigned similarity; unsigned additions; diff --git a/test/test_diff.py b/test/test_diff.py index f982d0194..2f4314d98 100644 --- a/test/test_diff.py +++ b/test/test_diff.py @@ -257,13 +257,13 @@ def test_diff_patch(self): self.assertEqual(diff.patch, PATCH) self.assertEqual(len(diff), len([patch for patch in diff])) - def test_diff_oids(self): + def test_diff_ids(self): commit_a = self.repo[COMMIT_SHA1_1] commit_b = self.repo[COMMIT_SHA1_2] patch = commit_a.tree.diff_to_tree(commit_b.tree)[0] - self.assertEqual(patch.old_oid, + self.assertEqual(patch.old_id, '7f129fd57e31e935c6d60a0c794efe4e6927664b') - self.assertEqual(patch.new_oid, + self.assertEqual(patch.new_id, 'af431f20fc541ed6d5afede3e2dc7160f6f01f16') def test_hunk_content(self): diff --git a/test/test_index.py b/test/test_index.py index 7bed86bb3..1426e7fa2 100644 --- a/test/test_index.py +++ b/test/test_index.py @@ -181,13 +181,13 @@ def test_change_attributes(self): index = self.repo.index entry = index['hello.txt'] ign_entry = index['.gitignore'] - self.assertNotEqual(ign_entry.oid, entry.oid) + self.assertNotEqual(ign_entry.id, entry.id) self.assertNotEqual(entry.mode, pygit2.GIT_FILEMODE_BLOB_EXECUTABLE) entry.path = 'foo.txt' - entry.oid = ign_entry.oid + entry.id = ign_entry.id entry.mode = pygit2.GIT_FILEMODE_BLOB_EXECUTABLE self.assertEqual('foo.txt', entry.path) - self.assertEqual(ign_entry.oid, entry.oid) + self.assertEqual(ign_entry.id, entry.id) self.assertEqual(pygit2.GIT_FILEMODE_BLOB_EXECUTABLE, entry.mode) def test_write_tree_to(self): @@ -201,7 +201,7 @@ class IndexEntryTest(utils.RepoTestCase): def test_create_entry(self): index = self.repo.index hello_entry = index['hello.txt'] - entry = pygit2.IndexEntry('README.md', hello_entry.oid, hello_entry.mode) + entry = pygit2.IndexEntry('README.md', hello_entry.id, hello_entry.mode) index.add(entry) tree_id = index.write_tree() self.assertEqual('60e769e57ae1d6a2ab75d8d253139e6260e1f912', str(tree_id)) diff --git a/test/test_note.py b/test/test_note.py index 74f08940d..4fcead56e 100644 --- a/test/test_note.py +++ b/test/test_note.py @@ -58,7 +58,7 @@ def test_create_note(self): def test_lookup_note(self): annotated_id = self.repo.head.target.hex note = self.repo.lookup_note(annotated_id) - self.assertEqual(NOTES[0][0], note.oid.hex) + self.assertEqual(NOTES[0][0], note.id.hex) self.assertEqual(NOTES[0][1], note.message) def test_remove_note(self): @@ -70,7 +70,7 @@ def test_remove_note(self): def test_iterate_notes(self): for i, note in enumerate(self.repo.notes()): - entry = (note.oid.hex, note.message, note.annotated_id) + entry = (note.id.hex, note.message, note.annotated_id) self.assertEqual(NOTES[i], entry) def test_iterate_non_existing_ref(self): diff --git a/test/test_repository.py b/test/test_repository.py index 71214ccef..8da731158 100644 --- a/test/test_repository.py +++ b/test/test_repository.py @@ -314,7 +314,7 @@ def test_merge_uptodate(self): merge_result = self.repo.merge(branch_oid) self.assertTrue(merge_result.is_uptodate) self.assertFalse(merge_result.is_fastforward) - self.assertEqual(None, merge_result.fastforward_oid) + self.assertEqual(None, merge_result.fastforward_id) self.assertEqual({}, self.repo.status()) def test_merge_fastforward(self): @@ -324,8 +324,8 @@ def test_merge_fastforward(self): self.assertFalse(merge_result.is_uptodate) self.assertTrue(merge_result.is_fastforward) # Asking twice to assure the reference counting is correct - self.assertEqual(branch_head_hex, merge_result.fastforward_oid.hex) - self.assertEqual(branch_head_hex, merge_result.fastforward_oid.hex) + self.assertEqual(branch_head_hex, merge_result.fastforward_id.hex) + self.assertEqual(branch_head_hex, merge_result.fastforward_id.hex) self.assertEqual({}, self.repo.status()) def test_merge_no_fastforward_no_conflicts(self): @@ -335,8 +335,8 @@ def test_merge_no_fastforward_no_conflicts(self): self.assertFalse(merge_result.is_uptodate) self.assertFalse(merge_result.is_fastforward) # Asking twice to assure the reference counting is correct - self.assertEqual(None, merge_result.fastforward_oid) - self.assertEqual(None, merge_result.fastforward_oid) + self.assertEqual(None, merge_result.fastforward_id) + self.assertEqual(None, merge_result.fastforward_id) self.assertEqual({'bye.txt': 1}, self.repo.status()) self.assertEqual({'bye.txt': 1}, self.repo.status()) # Checking the index works as expected @@ -351,8 +351,8 @@ def test_merge_no_fastforward_conflicts(self): self.assertFalse(merge_result.is_uptodate) self.assertFalse(merge_result.is_fastforward) # Asking twice to assure the reference counting is correct - self.assertEqual(None, merge_result.fastforward_oid) - self.assertEqual(None, merge_result.fastforward_oid) + self.assertEqual(None, merge_result.fastforward_id) + self.assertEqual(None, merge_result.fastforward_id) self.assertEqual({'.gitignore': 132}, self.repo.status()) self.assertEqual({'.gitignore': 132}, self.repo.status()) # Checking the index works as expected From a870a59f2a0216163f9b93378f2cf4704c2c9ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 23 Mar 2014 14:51:51 +0100 Subject: [PATCH 06/13] Adjust to option struct naming change --- src/repository.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/repository.c b/src/repository.c index 53f9649db..4c7ba006f 100644 --- a/src/repository.c +++ b/src/repository.c @@ -1360,7 +1360,7 @@ PyDoc_STRVAR(Repository_checkout_head__doc__, PyObject * Repository_checkout_head(Repository *self, PyObject *args) { - git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; + git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; unsigned int strategy; int err; @@ -1384,7 +1384,7 @@ PyDoc_STRVAR(Repository_checkout_index__doc__, PyObject * Repository_checkout_index(Repository *self, PyObject *args) { - git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; + git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; unsigned int strategy; int err; @@ -1408,7 +1408,7 @@ PyDoc_STRVAR(Repository_checkout_tree__doc__, PyObject * Repository_checkout_tree(Repository *self, PyObject *args) { - git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; + git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; unsigned int strategy; Object *py_object; int err; From 55037c23a34421c28558b44a0726539baa9f371a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 25 Mar 2014 03:14:02 +0100 Subject: [PATCH 07/13] Adjust to the merge changes There is no more MergeResult type. Instead, the user can use Repository.merge_analysis() to get an overview of their options and call git_merge() when they mean to merge. The git_merge() function now also performs a checkout. --- src/mergeresult.c | 145 ---------------------------------------- src/mergeresult.h | 37 ---------- src/pygit2.c | 8 ++- src/repository.c | 65 +++++++++++++----- src/types.h | 6 -- test/test_repository.py | 65 +++++++++--------- 6 files changed, 84 insertions(+), 242 deletions(-) delete mode 100644 src/mergeresult.c delete mode 100644 src/mergeresult.h diff --git a/src/mergeresult.c b/src/mergeresult.c deleted file mode 100644 index 4579e4b02..000000000 --- a/src/mergeresult.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2010-2014 The pygit2 contributors - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, - * as published by the Free Software Foundation. - * - * In addition to the permissions in the GNU General Public License, - * the authors give you unlimited permission to link the compiled - * version of this file into combinations with other programs, - * and to distribute those combinations without any restriction - * coming from the use of this file. (The General Public License - * restrictions do apply in other respects; for example, they cover - * modification of the file, and distribution when not linked into - * a combined executable.) - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#define PY_SSIZE_T_CLEAN -#include -#include "utils.h" -#include "types.h" -#include "oid.h" -#include "repository.h" -#include "mergeresult.h" - -extern PyTypeObject MergeResultType; -extern PyTypeObject IndexType; - -PyObject * -git_merge_result_to_python(git_merge_result *merge_result) -{ - MergeResult *py_merge_result; - - py_merge_result = PyObject_New(MergeResult, &MergeResultType); - if (!py_merge_result) - return NULL; - - py_merge_result->result = merge_result; - - return (PyObject*) py_merge_result; -} - -void -MergeResult_dealloc(MergeResult *self) -{ - git_merge_result_free(self->result); - PyObject_Del(self); -} - - -PyDoc_STRVAR(MergeResult_is_uptodate__doc__, "Is up to date"); - -PyObject * -MergeResult_is_uptodate__get__(MergeResult *self) -{ - if (git_merge_result_is_uptodate(self->result)) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; -} - -PyDoc_STRVAR(MergeResult_is_fastforward__doc__, "Is fastforward"); - -PyObject * -MergeResult_is_fastforward__get__(MergeResult *self) -{ - if (git_merge_result_is_fastforward(self->result)) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; -} - -PyDoc_STRVAR(MergeResult_fastforward_id__doc__, "Fastforward Oid"); - -PyObject * -MergeResult_fastforward_id__get__(MergeResult *self) -{ - if (git_merge_result_is_fastforward(self->result)) { - git_oid fastforward_id; - git_merge_result_fastforward_id(&fastforward_id, self->result); - return git_oid_to_python((const git_oid *)&fastforward_id); - } - else Py_RETURN_NONE; -} - -PyGetSetDef MergeResult_getseters[] = { - GETTER(MergeResult, is_uptodate), - GETTER(MergeResult, is_fastforward), - GETTER(MergeResult, fastforward_id), - {NULL}, -}; - -PyDoc_STRVAR(MergeResult__doc__, "MergeResult object."); - -PyTypeObject MergeResultType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_pygit2.MergeResult", /* tp_name */ - sizeof(MergeResult), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)MergeResult_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - MergeResult__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - MergeResult_getseters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; - diff --git a/src/mergeresult.h b/src/mergeresult.h deleted file mode 100644 index 74161ea9d..000000000 --- a/src/mergeresult.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2010-2014 The pygit2 contributors - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, - * as published by the Free Software Foundation. - * - * In addition to the permissions in the GNU General Public License, - * the authors give you unlimited permission to link the compiled - * version of this file into combinations with other programs, - * and to distribute those combinations without any restriction - * coming from the use of this file. (The General Public License - * restrictions do apply in other respects; for example, they cover - * modification of the file, and distribution when not linked into - * a combined executable.) - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDE_pygit2_merge_result_h -#define INCLUDE_pygit2_merge_result_h - -#define PY_SSIZE_T_CLEAN -#include -#include - -PyObject* git_merge_result_to_python(git_merge_result *merge_result); - -#endif diff --git a/src/pygit2.c b/src/pygit2.c index 2e80cc5b1..6fedc5d44 100644 --- a/src/pygit2.c +++ b/src/pygit2.c @@ -71,7 +71,6 @@ extern PyTypeObject NoteIterType; extern PyTypeObject BlameType; extern PyTypeObject BlameIterType; extern PyTypeObject BlameHunkType; -extern PyTypeObject MergeResultType; @@ -477,8 +476,11 @@ moduleinit(PyObject* m) ADD_CONSTANT_INT(m, GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES) /* Merge */ - INIT_TYPE(MergeResultType, NULL, NULL) - ADD_TYPE(m, MergeResult) + ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_NONE) + ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_NORMAL) + ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_UP_TO_DATE) + ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_FASTFORWARD) + ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_UNBORN) /* Global initialization of libgit2 */ git_threads_init(); diff --git a/src/repository.c b/src/repository.c index 4c7ba006f..ef9c8e38a 100644 --- a/src/repository.c +++ b/src/repository.c @@ -38,7 +38,6 @@ #include "remote.h" #include "branch.h" #include "blame.h" -#include "mergeresult.h" #include "signature.h" #include @@ -587,28 +586,61 @@ Repository_merge_base(Repository *self, PyObject *args) return git_oid_to_python(&oid); } +PyDoc_STRVAR(Repository_merge_analysis__doc__, + "merge_analysis(id) -> Integer\n" + "\n" + "Analyzes the given branch and determines the opportunities for merging\n" + "them into the HEAD of the repository\n" + "\n" + "The returned value is a mixture of the GIT_MERGE_ANALYSIS_NONE, _NORMAL,\n" + " _UP_TO_DATE, _FASTFORWARD and _UNBORN flags"); + +PyObject * +Repository_merge_analysis(Repository *self, PyObject *py_id) +{ + int err; + size_t len; + git_oid id; + git_merge_head *merge_head; + git_merge_analysis_t analysis; + + len = py_oid_to_git_oid(py_id, &id); + if (len == 0) + return NULL; + + err = git_merge_head_from_id(&merge_head, self->repo, &id); + if (err < 0) + return Error_set(err); + + err = git_merge_analysis(&analysis, self->repo, (const git_merge_head **) &merge_head, 1); + git_merge_head_free(merge_head); + + if (err < 0) + return Error_set(err); + + return PyLong_FromLong(analysis); +} + PyDoc_STRVAR(Repository_merge__doc__, - "merge(id) -> MergeResult\n" + "merge(id)\n" "\n" - "Merges the given id and returns the MergeResult.\n" + "Merges the given id into HEAD.\n" "\n" - "If the merge is fastforward the MergeResult will contain the new\n" - "fastforward oid.\n" - "If the branch is uptodate, nothing to merge, the MergeResult will\n" - "have the fastforward oid as None.\n" - "If the merge is not fastforward the MergeResult will have the status\n" - "produced by the merge, even if there are conflicts."); + "Merges the given commit(s) into HEAD, writing the results into the\n" + "working directory. Any changes are staged for commit and any conflicts\n" + "are written to the index. Callers should inspect the repository's\n" + "index after this completes, resolve any conflicts and prepare a\n" + "commit."); PyObject * Repository_merge(Repository *self, PyObject *py_oid) { - git_merge_result *merge_result; git_merge_head *oid_merge_head; git_oid oid; - const git_merge_opts default_opts = GIT_MERGE_OPTS_INIT; int err; size_t len; - PyObject *py_merge_result; + git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT; + git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT; len = py_oid_to_git_oid(py_oid, &oid); if (len == 0) @@ -618,15 +650,15 @@ Repository_merge(Repository *self, PyObject *py_oid) if (err < 0) return Error_set(err); - err = git_merge(&merge_result, self->repo, + err = git_merge(self->repo, (const git_merge_head **)&oid_merge_head, 1, - &default_opts); + &merge_opts, &checkout_opts); + git_merge_head_free(oid_merge_head); if (err < 0) return Error_set(err); - py_merge_result = git_merge_result_to_python(merge_result); - return py_merge_result; + Py_RETURN_NONE; } PyDoc_STRVAR(Repository_walk__doc__, @@ -1623,6 +1655,7 @@ PyMethodDef Repository_methods[] = { METHOD(Repository, TreeBuilder, METH_VARARGS), METHOD(Repository, walk, METH_VARARGS), METHOD(Repository, merge_base, METH_VARARGS), + METHOD(Repository, merge_analysis, METH_O), METHOD(Repository, merge, METH_O), METHOD(Repository, read, METH_O), METHOD(Repository, write, METH_VARARGS), diff --git a/src/types.h b/src/types.h index f1273990f..15ff74094 100644 --- a/src/types.h +++ b/src/types.h @@ -249,10 +249,4 @@ typedef struct { char boundary; } BlameHunk; -/* git_merge */ -typedef struct { - PyObject_HEAD - git_merge_result *result; -} MergeResult; - #endif diff --git a/test/test_repository.py b/test/test_repository.py index 8da731158..c35b0fd99 100644 --- a/test/test_repository.py +++ b/test/test_repository.py @@ -40,6 +40,8 @@ # Import from pygit2 from pygit2 import GIT_OBJ_ANY, GIT_OBJ_BLOB, GIT_OBJ_COMMIT +from pygit2 import GIT_MERGE_ANALYSIS_NONE, GIT_MERGE_ANALYSIS_NORMAL, GIT_MERGE_ANALYSIS_UP_TO_DATE +from pygit2 import GIT_MERGE_ANALYSIS_FASTFORWARD, GIT_MERGE_ANALYSIS_UNBORN from pygit2 import init_repository, clone_repository, discover_repository from pygit2 import Oid, Reference, hashfile import pygit2 @@ -308,57 +310,50 @@ class RepositoryTest_III(utils.RepoTestCaseForMerging): def test_merge_none(self): self.assertRaises(TypeError, self.repo.merge, None) - def test_merge_uptodate(self): + def test_merge_analysis_uptodate(self): branch_head_hex = '5ebeeebb320790caf276b9fc8b24546d63316533' - branch_oid = self.repo.get(branch_head_hex).id - merge_result = self.repo.merge(branch_oid) - self.assertTrue(merge_result.is_uptodate) - self.assertFalse(merge_result.is_fastforward) - self.assertEqual(None, merge_result.fastforward_id) + branch_id = self.repo.get(branch_head_hex).id + analysis = self.repo.merge_analysis(branch_id) + + self.assertTrue(analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE) + self.assertFalse(analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) self.assertEqual({}, self.repo.status()) - def test_merge_fastforward(self): + def test_merge_analysis_fastforward(self): branch_head_hex = 'e97b4cfd5db0fb4ebabf4f203979ca4e5d1c7c87' - branch_oid = self.repo.get(branch_head_hex).id - merge_result = self.repo.merge(branch_oid) - self.assertFalse(merge_result.is_uptodate) - self.assertTrue(merge_result.is_fastforward) - # Asking twice to assure the reference counting is correct - self.assertEqual(branch_head_hex, merge_result.fastforward_id.hex) - self.assertEqual(branch_head_hex, merge_result.fastforward_id.hex) + branch_id = self.repo.get(branch_head_hex).id + analysis = self.repo.merge_analysis(branch_id) + self.assertFalse(analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE) + self.assertTrue(analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) self.assertEqual({}, self.repo.status()) def test_merge_no_fastforward_no_conflicts(self): branch_head_hex = '03490f16b15a09913edb3a067a3dc67fbb8d41f1' - branch_oid = self.repo.get(branch_head_hex).id - merge_result = self.repo.merge(branch_oid) - self.assertFalse(merge_result.is_uptodate) - self.assertFalse(merge_result.is_fastforward) + branch_id = self.repo.get(branch_head_hex).id + analysis= self.repo.merge_analysis(branch_id) + self.assertFalse(analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE) + self.assertFalse(analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) # Asking twice to assure the reference counting is correct - self.assertEqual(None, merge_result.fastforward_id) - self.assertEqual(None, merge_result.fastforward_id) - self.assertEqual({'bye.txt': 1}, self.repo.status()) - self.assertEqual({'bye.txt': 1}, self.repo.status()) - # Checking the index works as expected - self.repo.index.remove('bye.txt') - self.repo.index.write() - self.assertEqual({'bye.txt': 128}, self.repo.status()) + self.assertEqual({}, self.repo.status()) + self.assertEqual({}, self.repo.status()) def test_merge_no_fastforward_conflicts(self): branch_head_hex = '1b2bae55ac95a4be3f8983b86cd579226d0eb247' - branch_oid = self.repo.get(branch_head_hex).id - merge_result = self.repo.merge(branch_oid) - self.assertFalse(merge_result.is_uptodate) - self.assertFalse(merge_result.is_fastforward) + branch_id = self.repo.get(branch_head_hex).id + + analysis = self.repo.merge_analysis(branch_id) + self.assertFalse(analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE) + self.assertFalse(analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) + + self.repo.merge(branch_id) + status = pygit2.GIT_STATUS_WT_NEW | pygit2.GIT_STATUS_INDEX_DELETED # Asking twice to assure the reference counting is correct - self.assertEqual(None, merge_result.fastforward_id) - self.assertEqual(None, merge_result.fastforward_id) - self.assertEqual({'.gitignore': 132}, self.repo.status()) - self.assertEqual({'.gitignore': 132}, self.repo.status()) + self.assertEqual({'.gitignore': status}, self.repo.status()) + self.assertEqual({'.gitignore': status}, self.repo.status()) # Checking the index works as expected self.repo.index.add('.gitignore') self.repo.index.write() - self.assertEqual({'.gitignore': 2}, self.repo.status()) + self.assertEqual({'.gitignore': pygit2.GIT_STATUS_INDEX_MODIFIED}, self.repo.status()) def test_merge_invalid_hex(self): branch_head_hex = '12345678' From 114e300b08f911d4923374e23ba67465c87edc01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 1 Apr 2014 19:56:10 +0200 Subject: [PATCH 08/13] Adjust to options changes We can now use a git_buf to extract the search path. --- src/options.c | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/src/options.c b/src/options.c index abfa4656a..1679a93d2 100644 --- a/src/options.c +++ b/src/options.c @@ -37,35 +37,16 @@ extern PyObject *GitError; static PyObject * get_search_path(long level) { - char *buf = NULL; - size_t len = 64; + git_buf buf = {NULL}; PyObject *py_path; - int error; - - do { - len *= 2; - char *tmp = realloc(buf, len); - if (!tmp) { - free(buf); - PyErr_NoMemory(); - return NULL; - } - buf = tmp; - - error = git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, level, buf, len); - } while(error == GIT_EBUFS); + int err; - if (error < 0) { - free(buf); - Error_set(error); - return NULL; - } - - if (!buf) - return NULL; + err = git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, level, &buf); + if (err < 0) + return Error_set(err); - py_path = to_unicode(buf, NULL, NULL); - free(buf); + py_path = to_unicode(buf.ptr, NULL, NULL); + git_buf_free(&buf); if (!py_path) return NULL; From b1bacdd8d58923859eb5b3f015a8f142c9420436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 18 May 2014 11:03:30 +0200 Subject: [PATCH 09/13] Wrap config snapshot functions These allow complex reads to come from the same version of the config. --- pygit2/config.py | 13 +++++++++++++ pygit2/decl.h | 2 ++ pygit2/repository.py | 13 +++++++++++++ 3 files changed, 28 insertions(+) diff --git a/pygit2/config.py b/pygit2/config.py index 6bbe6d20c..a757b9713 100644 --- a/pygit2/config.py +++ b/pygit2/config.py @@ -223,6 +223,19 @@ def add_file(self, path, level=0, force=0): err = C.git_config_add_file_ondisk(self._config, to_str(path), level, force) check_error(err) + def snapshot(self): + """Create a snapshot from this Config object + + This means that looking up multiple values will use the same version + of the configuration files + """ + + ccfg = ffi.new('git_config **') + err = C.git_config_snapshot(cfg, self._config) + check_error(err) + + return Config.from_c(self._repo, ccfg[0]) + # # Methods to parse a string according to the git-config rules # diff --git a/pygit2/decl.h b/pygit2/decl.h index a628f3b57..b26147292 100644 --- a/pygit2/decl.h +++ b/pygit2/decl.h @@ -255,6 +255,7 @@ typedef struct { } git_config_entry; int git_repository_config(git_config **out, git_repository *repo); +int git_repository_config_snapshot(git_config **out, git_repository *repo); void git_config_free(git_config *cfg); int git_config_get_string(const char **out, const git_config *cfg, const char *name); @@ -279,6 +280,7 @@ int git_config_multivar_iterator_new(git_config_iterator **out, const git_config int git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value); int git_config_new(git_config **out); +int git_config_snapshot(git_config **out, git_config *config); int git_config_open_ondisk(git_config **out, const char *path); int git_config_find_system(git_buf *out); int git_config_find_global(git_buf *out); diff --git a/pygit2/repository.py b/pygit2/repository.py index 3f18c2c40..db047f5ee 100644 --- a/pygit2/repository.py +++ b/pygit2/repository.py @@ -128,6 +128,19 @@ def config(self): return Config.from_c(self, cconfig[0]) + @property + def config_snapshot(self): + """A snapshot for this repositiory's configuration + + This allows reads over multiple values to use the same version + of the configuration files""" + + cconfig = ffi.new('git_config **') + err = C.git_repository_config_snapshot(cconfig, self._repo) + check_error(err) + + return Config.from_c(self, cconfig[0]) + # # References # From 491e352e4162542107e450f0223f87938b98f26c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sat, 7 Jun 2014 21:31:47 +0200 Subject: [PATCH 10/13] Update to latest libgit2 --- pygit2/decl.h | 8 ++++++++ src/repository.c | 12 +++++++----- test/test_repository.py | 8 ++++---- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/pygit2/decl.h b/pygit2/decl.h index b26147292..1d65df2c5 100644 --- a/pygit2/decl.h +++ b/pygit2/decl.h @@ -220,6 +220,13 @@ typedef struct git_checkout_options { const char *their_label; } git_checkout_options; +typedef enum { + GIT_CLONE_LOCAL_AUTO, + GIT_CLONE_LOCAL, + GIT_CLONE_NO_LOCAL, + GIT_CLONE_LOCAL_NO_LINKS, +} git_clone_local_t; + typedef struct git_clone_options { unsigned int version; @@ -228,6 +235,7 @@ typedef struct git_clone_options { int bare; int ignore_cert_errors; + git_clone_local_t local; const char *remote_name; const char* checkout_branch; git_signature *signature; diff --git a/src/repository.c b/src/repository.c index b2409ec27..0b12053a4 100644 --- a/src/repository.c +++ b/src/repository.c @@ -546,13 +546,14 @@ Repository_merge_base(Repository *self, PyObject *args) } PyDoc_STRVAR(Repository_merge_analysis__doc__, - "merge_analysis(id) -> Integer\n" + "merge_analysis(id) -> (Integer, Integer)\n" "\n" "Analyzes the given branch and determines the opportunities for merging\n" "them into the HEAD of the repository\n" "\n" - "The returned value is a mixture of the GIT_MERGE_ANALYSIS_NONE, _NORMAL,\n" - " _UP_TO_DATE, _FASTFORWARD and _UNBORN flags"); + "The first returned value is a mixture of the GIT_MERGE_ANALYSIS_NONE, _NORMAL,\n" + " _UP_TO_DATE, _FASTFORWARD and _UNBORN flags.\n" + "The second value is the user's preference from 'merge.ff'"); PyObject * Repository_merge_analysis(Repository *self, PyObject *py_id) @@ -562,6 +563,7 @@ Repository_merge_analysis(Repository *self, PyObject *py_id) git_oid id; git_merge_head *merge_head; git_merge_analysis_t analysis; + git_merge_preference_t preference; len = py_oid_to_git_oid(py_id, &id); if (len == 0) @@ -571,13 +573,13 @@ Repository_merge_analysis(Repository *self, PyObject *py_id) if (err < 0) return Error_set(err); - err = git_merge_analysis(&analysis, self->repo, (const git_merge_head **) &merge_head, 1); + err = git_merge_analysis(&analysis, &preference, self->repo, (const git_merge_head **) &merge_head, 1); git_merge_head_free(merge_head); if (err < 0) return Error_set(err); - return PyLong_FromLong(analysis); + return Py_BuildValue("(ii)", analysis, preference); } PyDoc_STRVAR(Repository_merge__doc__, diff --git a/test/test_repository.py b/test/test_repository.py index c35b0fd99..f40409287 100644 --- a/test/test_repository.py +++ b/test/test_repository.py @@ -313,7 +313,7 @@ def test_merge_none(self): def test_merge_analysis_uptodate(self): branch_head_hex = '5ebeeebb320790caf276b9fc8b24546d63316533' branch_id = self.repo.get(branch_head_hex).id - analysis = self.repo.merge_analysis(branch_id) + analysis, preference = self.repo.merge_analysis(branch_id) self.assertTrue(analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE) self.assertFalse(analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) @@ -322,7 +322,7 @@ def test_merge_analysis_uptodate(self): def test_merge_analysis_fastforward(self): branch_head_hex = 'e97b4cfd5db0fb4ebabf4f203979ca4e5d1c7c87' branch_id = self.repo.get(branch_head_hex).id - analysis = self.repo.merge_analysis(branch_id) + analysis, preference = self.repo.merge_analysis(branch_id) self.assertFalse(analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE) self.assertTrue(analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) self.assertEqual({}, self.repo.status()) @@ -330,7 +330,7 @@ def test_merge_analysis_fastforward(self): def test_merge_no_fastforward_no_conflicts(self): branch_head_hex = '03490f16b15a09913edb3a067a3dc67fbb8d41f1' branch_id = self.repo.get(branch_head_hex).id - analysis= self.repo.merge_analysis(branch_id) + analysis, preference = self.repo.merge_analysis(branch_id) self.assertFalse(analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE) self.assertFalse(analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) # Asking twice to assure the reference counting is correct @@ -341,7 +341,7 @@ def test_merge_no_fastforward_conflicts(self): branch_head_hex = '1b2bae55ac95a4be3f8983b86cd579226d0eb247' branch_id = self.repo.get(branch_head_hex).id - analysis = self.repo.merge_analysis(branch_id) + analysis, preference = self.repo.merge_analysis(branch_id) self.assertFalse(analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE) self.assertFalse(analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) From d3af09e86deba467daa8f6e058697c0f082561cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sat, 7 Jun 2014 21:45:10 +0200 Subject: [PATCH 11/13] Adjust to clone_into signature change --- pygit2/__init__.py | 2 +- pygit2/decl.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pygit2/__init__.py b/pygit2/__init__.py index eed50c81a..b4faa031b 100644 --- a/pygit2/__init__.py +++ b/pygit2/__init__.py @@ -189,7 +189,7 @@ def clone_into(repo, remote, branch=None): and calling this function. """ - err = C.git_clone_into(repo._repo, remote._remote, ffi.NULL, to_str(branch)) + err = C.git_clone_into(repo._repo, remote._remote, ffi.NULL, to_str(branch), ffi.NULL) if remote._stored_exception: raise remote._stored_exception diff --git a/pygit2/decl.h b/pygit2/decl.h index 603509b92..862f867bc 100644 --- a/pygit2/decl.h +++ b/pygit2/decl.h @@ -262,7 +262,8 @@ int git_clone_into( git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, - const char *branch); + const char *branch, + const git_signature *signature); /* * git_config From 130fff6f2c062235dade5b7ff6b7b74e517f9a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 8 Jun 2014 20:35:15 +0200 Subject: [PATCH 12/13] Bump required libgit2 version to 0.21 --- src/types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types.h b/src/types.h index 806e58978..e69b489eb 100644 --- a/src/types.h +++ b/src/types.h @@ -32,8 +32,8 @@ #include #include -#if !(LIBGIT2_VER_MAJOR == 0 && LIBGIT2_VER_MINOR == 20) -#error You need a compatible libgit2 version (v0.20.x) +#if !(LIBGIT2_VER_MAJOR == 0 && LIBGIT2_VER_MINOR == 21) +#error You need a compatible libgit2 version (v0.21.x) #endif /* From bde58d972742707094eeb16ac7b1d9dfdf75f342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 8 Jun 2014 20:35:21 +0200 Subject: [PATCH 13/13] Remote: make renaming take a method call Renaming a remote in pygit2 has been done via Remote.name= up to now, but this is inherently unsafe, as it provides no way to pass up the refspecs that libgit2 was unable to remap. In fact, if there ever was such problem, we would have segfaulted. libgit2 now provides a much more direct way of getting back the results, so expose it as the return value of Remote.rename(). This also removes the hint that a rename might be something that happens only to the in-memory structure. --- pygit2/decl.h | 10 +++++----- pygit2/remote.py | 19 +++++++++++++++---- test/test_remote.py | 9 +++++---- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/pygit2/decl.h b/pygit2/decl.h index 862f867bc..d3b5b022d 100644 --- a/pygit2/decl.h +++ b/pygit2/decl.h @@ -116,11 +116,11 @@ int git_remote_create( const char *url); const char * git_remote_name(const git_remote *remote); -typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, void *payload); -int git_remote_rename(git_remote *remote, - const char *new_name, - git_remote_rename_problem_cb callback, - void *payload); + +int git_remote_rename( + git_strarray *problems, + git_remote *remote, + const char *new_name); const char * git_remote_url(const git_remote *remote); int git_remote_set_url(git_remote *remote, const char* url); const char * git_remote_pushurl(const git_remote *remote); diff --git a/pygit2/remote.py b/pygit2/remote.py index 890e074e6..2b7f32d79 100644 --- a/pygit2/remote.py +++ b/pygit2/remote.py @@ -142,14 +142,25 @@ def name(self): return maybe_string(C.git_remote_name(self._remote)) - @name.setter - def name(self, value): - if not value: + def rename(self, new_name): + """Rename this remote + + Returns a list of fetch refspecs which were not in the standard format + and thus could not be remapped + """ + + if not new_name: raise ValueError("New remote name must be a non-empty string") - err = C.git_remote_rename(self._remote, to_str(value), ffi.NULL, ffi.NULL) + problems = ffi.new('git_strarray *') + err = C.git_remote_rename(problems, self._remote, to_str(new_name)) check_error(err) + ret = strarray_to_strings(problems) + C.git_strarray_free(problems) + + return ret + @property def url(self): """Url of the remote""" diff --git a/test/test_remote.py b/test/test_remote.py index 9c95f80cd..57814a386 100644 --- a/test/test_remote.py +++ b/test/test_remote.py @@ -61,11 +61,12 @@ def test_remote_rename(self): remote = self.repo.remotes[0] self.assertEqual(REMOTE_NAME, remote.name) - remote.name = 'new' + problems = remote.rename('new') + self.assertEqual([], problems) self.assertEqual('new', remote.name) - self.assertRaisesAssign(ValueError, remote, 'name', '') - self.assertRaisesAssign(ValueError, remote, 'name', None) + self.assertRaises(ValueError, remote.rename, '') + self.assertRaises(ValueError, remote.rename, None) def test_remote_set_url(self): @@ -153,7 +154,7 @@ def test_remote_list(self): def test_remote_save(self): remote = self.repo.remotes[0] - remote.name = 'new-name' + remote.rename('new-name') remote.url = 'http://example.com/test.git' remote.save()