added functionality to checkout from HEAD

This commit is contained in:
Nico von Geyso 2013-02-17 14:23:41 +01:00
parent db5e1443b6
commit b828eb926f
2 changed files with 39 additions and 21 deletions

@ -1068,35 +1068,43 @@ Repository_remotes__get__(Repository *self)
PyDoc_STRVAR(Repository_checkout__doc__, PyDoc_STRVAR(Repository_checkout__doc__,
"checkout(reference:Reference, [strategy:int])\n" "checkout([strategy:int, reference:Reference])\n"
"\n" "\n"
"Checks out a tree by a given reference and modifies the HEAD pointer.\n" "Checks out a tree by a given reference and modifies the HEAD pointer\n"
"Standard checkout strategy is pygit2.GIT_CHECKOUT_SAFE_CREATE"); "Standard checkout strategy is pygit2.GIT_CHECKOUT_SAFE_CREATE\n"
"If no reference is given, checkout will use HEAD instead.");
PyObject * PyObject *
Repository_checkout(Repository *self, PyObject *args) Repository_checkout(Repository *self, PyObject *args, PyObject *kw)
{ {
git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
unsigned int strategy = GIT_CHECKOUT_SAFE_CREATE; unsigned int strategy = GIT_CHECKOUT_SAFE_CREATE;
Reference* ref; Reference* ref = NULL;
git_object* object; git_object* object;
const git_oid* id; const git_oid* id;
int err; int err;
if (!PyArg_ParseTuple(args, "O!|I", &ReferenceType, &ref, &strategy)) static char *kwlist[] = {"strategy", "reference", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kw, "|IO!", kwlist,
&strategy, &ReferenceType, &ref))
return NULL; return NULL;
CHECK_REFERENCE(ref); if (ref != NULL) { // checkout from treeish
id = git_reference_target(ref->reference); id = git_reference_target(ref->reference);
err = git_object_lookup(&object, self->repo, id, GIT_OBJ_COMMIT); err = git_object_lookup(&object, self->repo, id, GIT_OBJ_COMMIT);
if(err == GIT_OK) { if(err == GIT_OK) {
opts.checkout_strategy = strategy; opts.checkout_strategy = strategy;
err = git_checkout_tree(self->repo, object, &opts); err = git_checkout_tree(self->repo, object, &opts);
if (err == GIT_OK) if (err == GIT_OK) {
err = git_repository_set_head(self->repo, err = git_repository_set_head(self->repo,
git_reference_name(ref->reference)); git_reference_name(ref->reference));
} }
}
} else { // checkout from head
opts.checkout_strategy = strategy;
err = git_checkout_head(self->repo, &opts);
}
if(err < 0) if(err < 0)
return Error_set(err); return Error_set(err);
@ -1122,7 +1130,7 @@ PyMethodDef Repository_methods[] = {
METHOD(Repository, status, METH_NOARGS), METHOD(Repository, status, METH_NOARGS),
METHOD(Repository, status_file, METH_O), METHOD(Repository, status_file, METH_O),
METHOD(Repository, create_remote, METH_VARARGS), METHOD(Repository, create_remote, METH_VARARGS),
METHOD(Repository, checkout, METH_VARARGS), METHOD(Repository, checkout, METH_VARARGS|METH_KEYWORDS),
{NULL} {NULL}
}; };

@ -187,16 +187,26 @@ class RepositoryTest_II(utils.RepoTestCase):
def test_checkout(self): def test_checkout(self):
ref_i18n = self.repo.lookup_reference('refs/heads/i18n') ref_i18n = self.repo.lookup_reference('refs/heads/i18n')
self.assertRaises(pygit2.GitError, self.repo.checkout, ref_i18n) # checkout i18n with conflicts and default strategy should
# not be possible
self.assertRaises(pygit2.GitError,
lambda: self.repo.checkout(reference=ref_i18n))
self.repo.checkout(ref_i18n, pygit2.GIT_CHECKOUT_FORCE) # checkout i18n with GIT_CHECKOUT_FORCE
self.assertTrue('new' not in self.repo.head.tree)
self.repo.checkout(pygit2.GIT_CHECKOUT_FORCE, ref_i18n)
self.assertEqual(self.repo.head.hex, self.repo[ref_i18n.target].hex) self.assertEqual(self.repo.head.hex, self.repo[ref_i18n.target].hex)
self.assertTrue('new' in self.repo.head.tree) self.assertTrue('new' in self.repo.head.tree)
self.assertTrue('bye.txt' not in self.repo.status()) self.assertTrue('bye.txt' not in self.repo.status())
ref_master = self.repo.lookup_reference('refs/heads/master') # some changes to working dir
self.repo.checkout(ref_master, pygit2.GIT_CHECKOUT_FORCE) with open(os.path.join(self.repo.workdir, 'bye.txt'), 'w') as f:
self.assertTrue('new' not in self.repo.head.tree) f.write('new content')
# checkout head
self.assertTrue('bye.txt' in self.repo.status())
self.repo.checkout(pygit2.GIT_CHECKOUT_FORCE)
self.assertTrue('bye.txt' not in self.repo.status())
class NewRepositoryTest(utils.NoRepoTestCase): class NewRepositoryTest(utils.NoRepoTestCase):
def test_new_repo(self): def test_new_repo(self):