checkout: move the code to cffi
As part of this, make the strategy part of **kwargs, in preparation for supporting more options.
This commit is contained in:
@@ -3,6 +3,7 @@ typedef ... git_remote;
|
||||
typedef ... git_refspec;
|
||||
typedef ... git_push;
|
||||
typedef ... git_cred;
|
||||
typedef ... git_object;
|
||||
typedef ... git_tree;
|
||||
typedef ... git_signature;
|
||||
typedef ... git_index;
|
||||
@@ -309,6 +310,11 @@ typedef enum {
|
||||
GIT_CLONE_LOCAL_NO_LINKS,
|
||||
} git_clone_local_t;
|
||||
|
||||
int git_checkout_init_options(git_checkout_options *opts, unsigned int version);
|
||||
int git_checkout_tree(git_repository *repo, const git_object *treeish, const git_checkout_options *opts);
|
||||
int git_checkout_head(git_repository *repo, const git_checkout_options *opts);
|
||||
int git_checkout_index(git_repository *repo, git_index *index, const git_checkout_options *opts);
|
||||
|
||||
/*
|
||||
* git_clone
|
||||
*/
|
||||
|
@@ -176,11 +176,52 @@ class Repository(_Repository):
|
||||
|
||||
return self.create_reference_symbolic(name, target, force)
|
||||
|
||||
|
||||
#
|
||||
# Checkout
|
||||
#
|
||||
def checkout(self, refname=None, strategy=GIT_CHECKOUT_SAFE_CREATE):
|
||||
@staticmethod
|
||||
def _checkout_args_to_options(**kwargs):
|
||||
# Create the options struct to pass
|
||||
copts = ffi.new('git_checkout_options *')
|
||||
check_error(C.git_checkout_init_options(copts, 1))
|
||||
|
||||
# pygit2's default is SAFE_CREATE
|
||||
copts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE
|
||||
# and go through the arguments to see what the user wanted
|
||||
for k, v in kwargs.iteritems():
|
||||
if k == 'strategy':
|
||||
copts.checkout_strategy = v
|
||||
|
||||
return copts
|
||||
|
||||
def checkout_head(self, **kwargs):
|
||||
"""Checkout HEAD
|
||||
|
||||
For arguments, see Repository.checkout().
|
||||
"""
|
||||
copts = Repository._checkout_args_to_options(**kwargs)
|
||||
check_error(C.git_checkout_head(self._repo, copts))
|
||||
|
||||
def checkout_index(self, **kwargs):
|
||||
"""Checkout the repository's index
|
||||
|
||||
For arguments, see Repository.checkout().
|
||||
"""
|
||||
copts = Repository._checkout_args_to_options(**kwargs)
|
||||
check_error(C.git_checkout_index(self._repo, ffi.NULL, copts))
|
||||
|
||||
def checkout_tree(self, treeish, **kwargs):
|
||||
"""Checkout the given treeish
|
||||
|
||||
For arguments, see Repository.checkout().
|
||||
"""
|
||||
copts = Repository._checkout_args_to_options(**kwargs)
|
||||
cptr = ffi.new('git_object **')
|
||||
ffi.buffer(cptr)[:] = treeish._pointer[:]
|
||||
|
||||
check_error(C.git_checkout_tree(self._repo, cptr[0], copts))
|
||||
|
||||
def checkout(self, refname=None, **kwargs):
|
||||
"""
|
||||
Checkout the given reference using the given strategy, and update
|
||||
the HEAD.
|
||||
@@ -193,14 +234,24 @@ class Repository(_Repository):
|
||||
|
||||
If no reference is given, checkout from the index.
|
||||
|
||||
Arguments:
|
||||
|
||||
:param str refname: The reference to checkout. After checkout,
|
||||
the current branch will be switched to this one.
|
||||
|
||||
:param int strategy: A ``GIT_CHECKOUT_`` value. The default is
|
||||
``GIT_CHECKOUT_SAFE_CREATE``.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
# Case 1: Checkout index
|
||||
if refname is None:
|
||||
return self.checkout_index(strategy)
|
||||
return self.checkout_index(**kwargs)
|
||||
|
||||
# Case 2: Checkout head
|
||||
if refname == 'HEAD':
|
||||
return self.checkout_head(strategy)
|
||||
return self.checkout_head(**kwargs)
|
||||
|
||||
# Case 3: Reference
|
||||
if type(refname) is Reference:
|
||||
@@ -211,7 +262,7 @@ class Repository(_Repository):
|
||||
|
||||
oid = reference.resolve().target
|
||||
treeish = self[oid]
|
||||
self.checkout_tree(treeish, strategy)
|
||||
self.checkout_tree(treeish, **kwargs)
|
||||
self.head = refname
|
||||
|
||||
|
||||
|
@@ -1288,79 +1288,6 @@ Repository__pointer__get__(Repository *self)
|
||||
return PyBytes_FromStringAndSize((char *) &self->repo, sizeof(git_repository *));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(Repository_checkout_head__doc__,
|
||||
"checkout_head(strategy)\n"
|
||||
"\n"
|
||||
"Checkout the head using the given strategy.");
|
||||
|
||||
PyObject *
|
||||
Repository_checkout_head(Repository *self, PyObject *args)
|
||||
{
|
||||
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
|
||||
unsigned int strategy;
|
||||
int err;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "I", &strategy))
|
||||
return NULL;
|
||||
|
||||
opts.checkout_strategy = strategy;
|
||||
err = git_checkout_head(self->repo, &opts);
|
||||
if (err < 0)
|
||||
return Error_set(err);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(Repository_checkout_index__doc__,
|
||||
"checkout_index(strategy)\n"
|
||||
"\n"
|
||||
"Checkout the index using the given strategy.");
|
||||
|
||||
PyObject *
|
||||
Repository_checkout_index(Repository *self, PyObject *args)
|
||||
{
|
||||
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
|
||||
unsigned int strategy;
|
||||
int err;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "I", &strategy))
|
||||
return NULL;
|
||||
|
||||
opts.checkout_strategy = strategy;
|
||||
err = git_checkout_index(self->repo, NULL, &opts);
|
||||
if (err < 0)
|
||||
return Error_set(err);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(Repository_checkout_tree__doc__,
|
||||
"checkout_tree(treeish, strategy)\n"
|
||||
"\n"
|
||||
"Checkout the given tree, commit or tag, using the given strategy.");
|
||||
|
||||
PyObject *
|
||||
Repository_checkout_tree(Repository *self, PyObject *args)
|
||||
{
|
||||
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
|
||||
unsigned int strategy;
|
||||
Object *py_object;
|
||||
int err;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O!I", &ObjectType, &py_object, &strategy))
|
||||
return NULL;
|
||||
|
||||
opts.checkout_strategy = strategy;
|
||||
err = git_checkout_tree(self->repo, py_object->obj, &opts);
|
||||
if (err < 0)
|
||||
return Error_set(err);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(Repository_notes__doc__, "");
|
||||
|
||||
PyObject *
|
||||
@@ -1570,9 +1497,6 @@ PyMethodDef Repository_methods[] = {
|
||||
METHOD(Repository, revparse_single, METH_O),
|
||||
METHOD(Repository, status, METH_NOARGS),
|
||||
METHOD(Repository, status_file, METH_O),
|
||||
METHOD(Repository, checkout_head, METH_VARARGS),
|
||||
METHOD(Repository, checkout_index, METH_VARARGS),
|
||||
METHOD(Repository, checkout_tree, METH_VARARGS),
|
||||
METHOD(Repository, notes, METH_VARARGS),
|
||||
METHOD(Repository, create_note, METH_VARARGS),
|
||||
METHOD(Repository, lookup_note, METH_VARARGS),
|
||||
|
@@ -213,7 +213,7 @@ class RepositoryTest_II(utils.RepoTestCase):
|
||||
head = self.repo.head
|
||||
head = self.repo[head.target]
|
||||
self.assertTrue('new' not in head.tree)
|
||||
self.repo.checkout(ref_i18n, pygit2.GIT_CHECKOUT_FORCE)
|
||||
self.repo.checkout(ref_i18n, strategy=pygit2.GIT_CHECKOUT_FORCE)
|
||||
|
||||
head = self.repo.head
|
||||
head = self.repo[head.target]
|
||||
@@ -243,7 +243,7 @@ class RepositoryTest_II(utils.RepoTestCase):
|
||||
self.assertTrue('bye.txt' in self.repo.status())
|
||||
|
||||
# checkout from head will reset index as well
|
||||
self.repo.checkout('HEAD', pygit2.GIT_CHECKOUT_FORCE)
|
||||
self.repo.checkout('HEAD', strategy=pygit2.GIT_CHECKOUT_FORCE)
|
||||
self.assertTrue('bye.txt' not in self.repo.status())
|
||||
|
||||
def test_merge_base(self):
|
||||
|
Reference in New Issue
Block a user