diff --git a/src/pygit2.c b/src/pygit2.c index e41015a..41613e3 100644 --- a/src/pygit2.c +++ b/src/pygit2.c @@ -264,6 +264,18 @@ moduleinit(PyObject* m) PyModule_AddIntConstant(m, "GIT_DIFF_RECURSE_UNTRACKED_DIRS", GIT_DIFF_RECURSE_UNTRACKED_DIRS); + /* Flags for diff find similar */ + PyModule_AddIntConstant(m, "GIT_DIFF_FIND_RENAMES", // --find-renames + GIT_DIFF_FIND_RENAMES); + PyModule_AddIntConstant(m, "GIT_DIFF_FIND_RENAMES_FROM_REWRITES", // --break-rewrites=N + GIT_DIFF_FIND_RENAMES_FROM_REWRITES); + PyModule_AddIntConstant(m, "GIT_DIFF_FIND_COPIES", // --find-copies + GIT_DIFF_FIND_COPIES); + PyModule_AddIntConstant(m, "GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED", // --find-copies-harder + GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED); + PyModule_AddIntConstant(m, "GIT_DIFF_FIND_AND_BREAK_REWRITES", // --break-rewrites=/M + GIT_DIFF_FIND_AND_BREAK_REWRITES); + /* Flags for diffed files */ PyModule_AddIntConstant(m, "GIT_DIFF_FILE_VALID_OID", GIT_DIFF_FILE_VALID_OID); diff --git a/src/pygit2/diff.c b/src/pygit2/diff.c index 81751ae..526a312 100644 --- a/src/pygit2/diff.c +++ b/src/pygit2/diff.c @@ -177,10 +177,11 @@ static int diff_file_cb(void *cb_data, const git_diff_delta *delta, Py_DECREF(files); } - file = Py_BuildValue("(s,s,i)", + file = Py_BuildValue("(s,s,i,i)", delta->old_file.path, delta->new_file.path, - delta->status + delta->status, + delta->similarity ); if (PyList_Append(files, file) == 0) { @@ -355,6 +356,24 @@ Diff_merge(Diff *self, PyObject *args) Py_RETURN_NONE; } +PyObject * +Diff_find_similar(Diff *self, PyObject *args) +{ + int err; + git_diff_options opts = {0}; + + if (!PyArg_ParseTuple(args, "|i", &opts.flags)) + return NULL; + + err = git_diff_find_similar(self->diff, &opts); + if (err < 0) + return Error_set(err); + + Py_XDECREF(self->diff_changes); + self->diff_changes = NULL; + Py_RETURN_NONE; +} + static void Diff_dealloc(Diff *self) { @@ -373,6 +392,8 @@ PyGetSetDef Diff_getseters[] = { static PyMethodDef Diff_methods[] = { {"merge", (PyCFunction)Diff_merge, METH_VARARGS, "Merge one diff into another."}, + {"find_similar", (PyCFunction)Diff_find_similar, METH_VARARGS, + "Find renamed files in diff."}, {NULL, NULL, 0, NULL} }; diff --git a/test/data/testrepo.git/objects/05/6e626e51b1fc1ee2182800e399ed8d84c8f082 b/test/data/testrepo.git/objects/05/6e626e51b1fc1ee2182800e399ed8d84c8f082 new file mode 100644 index 0000000..9ec45d6 Binary files /dev/null and b/test/data/testrepo.git/objects/05/6e626e51b1fc1ee2182800e399ed8d84c8f082 differ diff --git a/test/data/testrepo.git/objects/1a/f81f24e48f92009ca02a874edb6151c71f60de b/test/data/testrepo.git/objects/1a/f81f24e48f92009ca02a874edb6151c71f60de new file mode 100644 index 0000000..46f991f Binary files /dev/null and b/test/data/testrepo.git/objects/1a/f81f24e48f92009ca02a874edb6151c71f60de differ diff --git a/test/data/testrepo.git/refs/heads/master b/test/data/testrepo.git/refs/heads/master index 101232d..b8e9848 100644 --- a/test/data/testrepo.git/refs/heads/master +++ b/test/data/testrepo.git/refs/heads/master @@ -1 +1 @@ -ccca47fbb26183e71a7a46d165299b84e2e6c0b3 +056e626e51b1fc1ee2182800e399ed8d84c8f082 diff --git a/test/test_config.py b/test/test_config.py index aa5063b..cc64a53 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -78,7 +78,7 @@ class ConfigTest(utils.RepoTestCase): self.assertFalse(config_read['core.bare']) self.assertTrue('core.editor' in config_read) self.assertEqual(config_read['core.editor'], 'ed') - + def test_add(self): config = pygit2.Config() diff --git a/test/test_diff.py b/test/test_diff.py index 6fa9ba0..e79ddf2 100644 --- a/test/test_diff.py +++ b/test/test_diff.py @@ -38,6 +38,7 @@ COMMIT_SHA1_1 = '5fe808e8953c12735680c257f56600cb0de44b10' COMMIT_SHA1_2 = 'c2792cfa289ae6321ecf2cd5806c2194b0fd070c' COMMIT_SHA1_3 = '2cdae28389c059815e951d0bb9eed6533f61a46b' COMMIT_SHA1_4 = 'ccca47fbb26183e71a7a46d165299b84e2e6c0b3' +COMMIT_SHA1_5 = '056e626e51b1fc1ee2182800e399ed8d84c8f082' PATCH = b"""diff --git a/a b/a index 7f129fd..af431f2 100644 @@ -119,7 +120,7 @@ class DiffTest(utils.BareRepoTestCase): # self.assertIsNotNone is 2.7 only self.assertTrue(diff is not None) # self.assertIn is 2.7 only - self.assertTrue(('a','a', 3) in diff.changes['files']) + self.assertTrue(('a','a', 3, 0) in diff.changes['files']) self.assertEqual(2, len(diff.changes['hunks'])) hunk = diff.changes['hunks'][0] @@ -162,13 +163,13 @@ class DiffTest(utils.BareRepoTestCase): self.assertTrue(diff_c is not None) # assertIn / assertNotIn are 2.7 only - self.assertTrue(('b','b', 3) not in diff_b.changes['files']) - self.assertTrue(('b','b', 3) in diff_c.changes['files']) + self.assertTrue(('b','b', 3, 0) not in diff_b.changes['files']) + self.assertTrue(('b','b', 3, 0) in diff_c.changes['files']) diff_b.merge(diff_c) # assertIn is 2.7 only - self.assertTrue(('b','b', 3) in diff_b.changes['files']) + self.assertTrue(('b','b', 3, 0) in diff_b.changes['files']) hunk = diff_b.changes['hunks'][1] self.assertEqual(hunk.old_start, 1) @@ -203,5 +204,16 @@ class DiffTest(utils.BareRepoTestCase): self.assertEqual(diff.changes['hunks'][0].old_oid, '7f129fd57e31e935c6d60a0c794efe4e6927664b') self.assertEqual(diff.changes['hunks'][0].new_oid, 'af431f20fc541ed6d5afede3e2dc7160f6f01f16') + def test_find_similar(self): + commit_a = self.repo[COMMIT_SHA1_4] + commit_b = self.repo[COMMIT_SHA1_5] + + #~ Must pass GIT_DIFF_INCLUDE_UNMODIFIED if you expect to emulate + #~ --find-copies-harder during rename transformion... + diff = commit_a.tree.diff(commit_b.tree, pygit2.GIT_DIFF_INCLUDE_UNMODIFIED) + self.assertFalse(('a', 'a.copy', 5, 100) in diff.changes['files']) + diff.find_similar(pygit2.GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED) + self.assertTrue(('a', 'a.copy', 5, 100) in diff.changes['files']) + if __name__ == '__main__': unittest.main() diff --git a/test/test_repository.py b/test/test_repository.py index c2c05ec..10dd9f5 100644 --- a/test/test_repository.py +++ b/test/test_repository.py @@ -39,8 +39,8 @@ from pygit2 import GIT_OBJ_ANY, GIT_OBJ_BLOB, GIT_OBJ_COMMIT, init_repository, \ from . import utils -HEAD_SHA = 'ccca47fbb26183e71a7a46d165299b84e2e6c0b3' -PARENT_SHA = '2cdae28389c059815e951d0bb9eed6533f61a46b' # HEAD^ +HEAD_SHA = '056e626e51b1fc1ee2182800e399ed8d84c8f082' +PARENT_SHA = 'ccca47fbb26183e71a7a46d165299b84e2e6c0b3' # HEAD^ A_HEX_SHA = 'af431f20fc541ed6d5afede3e2dc7160f6f01f16' A_BIN_SHA = binascii.unhexlify(A_HEX_SHA.encode('ascii'))