diff --git a/src/pygit2/diff.c b/src/pygit2/diff.c index a1d5e2e..da6c514 100644 --- a/src/pygit2/diff.c +++ b/src/pygit2/diff.c @@ -53,8 +53,8 @@ static int diff_hunk_cb( hunks = PyDict_GetItemString(cb_data, "hunks"); if(hunks == NULL) { - hunks = PyList_New(0); - PyDict_SetItemString(cb_data, "hunks", hunks); + hunks = PyList_New(0); + PyDict_SetItemString(cb_data, "hunks", hunks); } hunk = (Hunk*) PyType_GenericNew(&HunkType, NULL, NULL); @@ -237,6 +237,24 @@ PyTypeObject HunkType = { 0, /* tp_new */ }; +PyObject * +Diff_merge(Diff *self, PyObject *args) +{ + Diff *py_diff; + int err; + + if (!PyArg_ParseTuple(args, "O!", &DiffType, &py_diff)) + return NULL; + if (py_diff->repo->repo != self->repo->repo) + return Error_set(GIT_ERROR); + + err = git_diff_merge(self->diff, py_diff->diff); + if (err < 0) + return Error_set(err); + + Py_RETURN_NONE; +} + static void Diff_dealloc(Diff *self) { @@ -251,6 +269,12 @@ PyGetSetDef Diff_getseters[] = { {NULL} }; +static PyMethodDef Diff_methods[] = { + {"merge", (PyCFunction)Diff_merge, METH_VARARGS, + "Merge one diff into another."}, + {NULL, NULL, 0, NULL} +}; + PyTypeObject DiffType = { PyVarObject_HEAD_INIT(NULL, 0) "pygit2.Diff", /* tp_name */ @@ -279,7 +303,7 @@ PyTypeObject DiffType = { 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - 0, /* tp_methods */ + Diff_methods, /* tp_methods */ 0, /* tp_members */ Diff_getseters, /* tp_getset */ 0, /* tp_base */ diff --git a/test/data/testrepo.git/objects/2a/d1d3456c5c4a1c9e40aeeddb9cd20b409623c8 b/test/data/testrepo.git/objects/2a/d1d3456c5c4a1c9e40aeeddb9cd20b409623c8 new file mode 100644 index 0000000..1c1c60d Binary files /dev/null and b/test/data/testrepo.git/objects/2a/d1d3456c5c4a1c9e40aeeddb9cd20b409623c8 differ diff --git a/test/data/testrepo.git/objects/2c/dae28389c059815e951d0bb9eed6533f61a46b b/test/data/testrepo.git/objects/2c/dae28389c059815e951d0bb9eed6533f61a46b new file mode 100644 index 0000000..4210e78 --- /dev/null +++ b/test/data/testrepo.git/objects/2c/dae28389c059815e951d0bb9eed6533f61a46b @@ -0,0 +1,2 @@ +xOIj1YA֑ }!д̂ ~~I^[PE<7E:3RMu>D +䋡 scjquV:/ ; %ĈH#V~4]K ^7=={7|B~{\rMQHz])ۧST+ ?.mEZ}s] \ No newline at end of file diff --git a/test/data/testrepo.git/objects/39/a3001fcc2b9541fdcf4be2d662618a5d213f47 b/test/data/testrepo.git/objects/39/a3001fcc2b9541fdcf4be2d662618a5d213f47 new file mode 100644 index 0000000..aa5e5ff --- /dev/null +++ b/test/data/testrepo.git/objects/39/a3001fcc2b9541fdcf4be2d662618a5d213f47 @@ -0,0 +1 @@ +xO9N1$+:Gz|=B|G{m-s/ RJ6w"p*蝵Q4'CK^b&/NUG1B=4)1)늝g11qBn\AWx9d}[!&FgEϸg` 9p>)cj.4+]̝OW)M]= \ No newline at end of file diff --git a/test/data/testrepo.git/objects/6a/270c81bc80b59591e0d2e3abd7d03450c0c395 b/test/data/testrepo.git/objects/6a/270c81bc80b59591e0d2e3abd7d03450c0c395 new file mode 100644 index 0000000..7db6959 Binary files /dev/null and b/test/data/testrepo.git/objects/6a/270c81bc80b59591e0d2e3abd7d03450c0c395 differ diff --git a/test/data/testrepo.git/objects/72/abb8755b2cc6c4e40fd9f50f54384d973a2f22 b/test/data/testrepo.git/objects/72/abb8755b2cc6c4e40fd9f50f54384d973a2f22 new file mode 100644 index 0000000..ad41240 Binary files /dev/null and b/test/data/testrepo.git/objects/72/abb8755b2cc6c4e40fd9f50f54384d973a2f22 differ diff --git a/test/data/testrepo.git/objects/97/d615e1bc273c40c94a726814e7b93fdb5a1b36 b/test/data/testrepo.git/objects/97/d615e1bc273c40c94a726814e7b93fdb5a1b36 new file mode 100644 index 0000000..2a7331e Binary files /dev/null and b/test/data/testrepo.git/objects/97/d615e1bc273c40c94a726814e7b93fdb5a1b36 differ diff --git a/test/data/testrepo.git/refs/heads/master b/test/data/testrepo.git/refs/heads/master index b7105a1..e863952 100644 --- a/test/data/testrepo.git/refs/heads/master +++ b/test/data/testrepo.git/refs/heads/master @@ -1 +1 @@ -5fe808e8953c12735680c257f56600cb0de44b10 +2cdae28389c059815e951d0bb9eed6533f61a46b diff --git a/test/test_diff.py b/test/test_diff.py index fadaff2..e83269c 100644 --- a/test/test_diff.py +++ b/test/test_diff.py @@ -39,6 +39,7 @@ __author__ = 'Nico.Geyso@FU-Berlin.de (Nico von Geyso)' COMMIT_SHA1_1 = '5fe808e8953c12735680c257f56600cb0de44b10' COMMIT_SHA1_2 = 'c2792cfa289ae6321ecf2cd5806c2194b0fd070c' +COMMIT_SHA1_3 = '2cdae28389c059815e951d0bb9eed6533f61a46b' PATCH = b"""diff --git a/a b/a index 7f129fd..af431f2 100644 --- a/a @@ -85,6 +86,36 @@ class DiffTest(utils.BareRepoTestCase): self.assertEqual(hunk.old_data, b'a contents 2\n') self.assertEqual(hunk.new_data, b'a contents\n') + def test_diff_merge(self): + commit_a = self.repo[COMMIT_SHA1_1] + commit_b = self.repo[COMMIT_SHA1_2] + commit_c = self.repo[COMMIT_SHA1_3] + + diff_b = commit_a.tree.diff(commit_b.tree) + self.assertIsNotNone(diff_b) + + diff_c = commit_b.tree.diff(commit_c.tree) + self.assertIsNotNone(diff_c) + + self.assertNotIn(('b','b', 3), diff_b.changes['files']) + self.assertIn(('b','b', 3), diff_c.changes['files']) + + diff_b.merge(diff_c) + + self.assertIn(('b','b', 3), diff_b.changes['files']) + + hunk = diff_b.changes['hunks'][1] + self.assertEqual(hunk.old_start, 1) + self.assertEqual(hunk.old_lines, 0) + self.assertEqual(hunk.new_start, 1) + self.assertEqual(hunk.new_lines, 0) + + self.assertEqual(hunk.old_file, 'b') + self.assertEqual(hunk.new_file, 'b') + + self.assertEqual(hunk.old_data, b'b contents\n') + self.assertEqual(hunk.new_data, b'b contents 2\n') + def test_diff_patch(self): commit_a = self.repo[COMMIT_SHA1_1] commit_b = self.repo[COMMIT_SHA1_2]