diff --git a/src/repository.c b/src/repository.c index f8a34e9bd..d4e483f5c 100755 --- a/src/repository.c +++ b/src/repository.c @@ -1885,9 +1885,9 @@ Repository_list_worktrees(Repository *self, PyObject *args) } PyDoc_STRVAR(Repository_apply__doc__, - "apply(id)\n" + "apply(diff or patch)\n" "\n" - "Applies the given id into HEAD.\n" + "Applies the given patch into HEAD.\n" "\n" "Applies a diff into HEAD, writing the results into the\n" "working directory."); @@ -1907,6 +1907,27 @@ Repository_apply(Repository *self, PyObject *py_diff) Py_RETURN_NONE; } +PyDoc_STRVAR(Repository_applies__doc__, + "applies(diff) -> bool\n" + "\n" + "Tests if the given patch will apply to HEAD, without writing it."); + +PyObject * +Repository_applies(Repository *self, PyObject *py_diff) +{ + int err; + git_apply_location_t location = GIT_APPLY_LOCATION_INDEX; + git_apply_options options = GIT_APPLY_OPTIONS_INIT; + options.flags |= GIT_APPLY_CHECK; + + err = git_apply(self->repo, ((Diff*)py_diff)->diff, location, &options); + + if (err < 0) + Py_RETURN_FALSE; + + Py_RETURN_TRUE; +} + PyDoc_STRVAR(Repository_set_odb__doc__, "set_odb(odb: Odb)\n" "\n" @@ -1954,6 +1975,7 @@ PyMethodDef Repository_methods[] = { METHOD(Repository, merge, METH_O), METHOD(Repository, cherrypick, METH_O), METHOD(Repository, apply, METH_O), + METHOD(Repository, applies, METH_O), METHOD(Repository, create_reference_direct, METH_VARARGS), METHOD(Repository, create_reference_symbolic, METH_VARARGS), METHOD(Repository, compress_references, METH_NOARGS), diff --git a/test/test_repository.py b/test/test_repository.py index 4a20ad30d..8fe5bc470 100644 --- a/test/test_repository.py +++ b/test/test_repository.py @@ -300,6 +300,28 @@ def test_diff_patch(testrepo): assert content == new_content +def test_diff_applies(testrepo): + new_content = ['bye world', 'adiĆ³s', 'au revoir monde'] + new_content = ''.join(x + os.linesep for x in new_content) + + # create the patch + with open(os.path.join(testrepo.workdir, 'hello.txt'), 'wb') as f: + f.write(new_content.encode('utf-8')) + + patch = testrepo.diff().patch + + # rollback all changes + testrepo.checkout('HEAD', strategy=pygit2.GIT_CHECKOUT_FORCE) + + # apply the patch and compare + diff = pygit2.Diff.parse_diff(patch) + assert testrepo.applies(diff) + + with open(os.path.join(testrepo.workdir, 'hello.txt'), 'rb') as f: + content = f.read().decode('utf-8') + + assert content != new_content + def test_default_signature(testrepo):