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:
parent
c267891d1f
commit
b7e906eee9
@ -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)
|
||||
|
57
src/config.c
57
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
52
src/diff.c
52
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);
|
||||
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
29
src/pygit2.c
29
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)
|
||||
|
@ -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;
|
||||
|
@ -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}",
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user