diff --git a/docs/merge.rst b/docs/merge.rst index 55e411a..f2ee278 100644 --- a/docs/merge.rst +++ b/docs/merge.rst @@ -2,4 +2,37 @@ Merge ********************************************************************** +.. contents:: + .. automethod:: pygit2.Repository.merge_base +.. automethod:: pygit2.Repository.merge + +The merge method +================= + +The method does a merge over the current working copy. +It gets an Oid object as a parameter and returns a MergeResult object. + +As its name says, it only does the merge, does not commit nor update the +branch reference in the case of a fastforward. + +For the moment, the merge does not support options, it will perform the +merge with the default ones defined in GIT_MERGE_OPTS_INIT libgit2 constant. + +Example:: + + >>> branch_head_hex = '5ebeeebb320790caf276b9fc8b24546d63316533' + >>> branch_oid = self.repo.get(branch_head_hex).oid + >>> merge_result = self.repo.merge(branch_oid) + +The MergeResult object +====================== + +Represents the result of a merge and contains this fields: + +- is_uptodate: bool, if there wasn't any merge because the repo was already + up to date +- is_fastforward: bool, whether the merge was fastforward or not +- fastforward_oid: Oid, in the case it was a fastforward, this is the + forwarded Oid. +- index: represents the repository index after the merge diff --git a/src/mergeresult.c b/src/mergeresult.c index dfad78b..1493d6a 100644 --- a/src/mergeresult.c +++ b/src/mergeresult.c @@ -39,26 +39,14 @@ extern PyTypeObject IndexType; PyObject * git_merge_result_to_python(git_merge_result *merge_result, Repository *repo) { - git_oid fastforward_oid; MergeResult *py_merge_result; py_merge_result = PyObject_New(MergeResult, &MergeResultType); + if (!py_merge_result) + return NULL; - py_merge_result->is_uptodate = git_merge_result_is_uptodate(merge_result) == GIT_CVAR_TRUE; - - if (git_merge_result_is_fastforward(merge_result) == GIT_CVAR_TRUE) - { - py_merge_result->is_fastforward = GIT_CVAR_TRUE; - git_merge_result_fastforward_oid(&fastforward_oid, merge_result); - py_merge_result->fastforward_oid = git_oid_to_python((const git_oid *)&fastforward_oid); - } - else - { - py_merge_result->is_fastforward = GIT_CVAR_FALSE; - py_merge_result->fastforward_oid = NULL; - } - - py_merge_result->status = Repository_status(repo); + py_merge_result->result = merge_result; + py_merge_result->repo = repo; return (PyObject*) py_merge_result; } @@ -68,7 +56,7 @@ PyDoc_STRVAR(MergeResult_is_uptodate__doc__, "Is up to date"); PyObject * MergeResult_is_uptodate__get__(MergeResult *self) { - if (self->is_uptodate) + if (git_merge_result_is_uptodate(self->result)) Py_RETURN_TRUE; else Py_RETURN_FALSE; @@ -79,7 +67,7 @@ PyDoc_STRVAR(MergeResult_is_fastforward__doc__, "Is fastforward"); PyObject * MergeResult_is_fastforward__get__(MergeResult *self) { - if (self->is_fastforward) + if (git_merge_result_is_fastforward(self->result)) Py_RETURN_TRUE; else Py_RETURN_FALSE; @@ -90,29 +78,43 @@ PyDoc_STRVAR(MergeResult_fastforward_oid__doc__, "Fastforward Oid"); PyObject * MergeResult_fastforward_oid__get__(MergeResult *self) { - if (self->is_fastforward) - { - Py_INCREF(self->fastforward_oid); - return self->fastforward_oid; + if (git_merge_result_is_fastforward(self->result)) { + git_oid fastforward_oid; + git_merge_result_fastforward_oid(&fastforward_oid, self->result); + return git_oid_to_python((const git_oid *)&fastforward_oid); } - else - Py_RETURN_NONE; + else Py_RETURN_NONE; } -PyDoc_STRVAR(MergeResult_status__doc__, "Merge repository status"); +PyDoc_STRVAR(MergeResult_index__doc__, "Merge repository index"); PyObject * -MergeResult_status__get__(MergeResult *self) +MergeResult_index__get__(MergeResult *self) { - Py_INCREF(self->status); - return self->status; + git_index *index; + Index *py_index; + int err; + + err = git_repository_index(&index, self->repo->repo); + if (err < 0) + return NULL; + + py_index = PyObject_GC_New(Index, &IndexType); + if (!py_index) { + return NULL; + } + + py_index->repo = self->repo; + py_index->index = index; + Py_INCREF(py_index); + return (PyObject*) py_index; } PyGetSetDef MergeResult_getseters[] = { GETTER(MergeResult, is_uptodate), GETTER(MergeResult, is_fastforward), GETTER(MergeResult, fastforward_oid), - GETTER(MergeResult, status), + GETTER(MergeResult, index), {NULL}, }; diff --git a/src/repository.c b/src/repository.c index 81396f9..f590507 100644 --- a/src/repository.c +++ b/src/repository.c @@ -621,7 +621,6 @@ Repository_merge(Repository *self, PyObject *py_oid) py_merge_result = git_merge_result_to_python(merge_result, self); git_merge_head_free(oid_merge_head); - git_merge_result_free(merge_result); return py_merge_result; diff --git a/test/test_repository.py b/test/test_repository.py index c44c3df..0ba5766 100644 --- a/test/test_repository.py +++ b/test/test_repository.py @@ -314,7 +314,7 @@ class RepositoryTest_III(utils.RepoTestCaseForMerging): self.assertTrue(merge_result.is_uptodate) self.assertFalse(merge_result.is_fastforward) self.assertEquals(None, merge_result.fastforward_oid) - self.assertEquals({}, merge_result.status) + self.assertEquals({}, self.repo.status()) def test_merge_fastforward(self): branch_head_hex = 'e97b4cfd5db0fb4ebabf4f203979ca4e5d1c7c87' @@ -325,7 +325,7 @@ class RepositoryTest_III(utils.RepoTestCaseForMerging): # Asking twice to assure the reference counting is correct self.assertEquals(branch_head_hex, merge_result.fastforward_oid.hex) self.assertEquals(branch_head_hex, merge_result.fastforward_oid.hex) - self.assertEquals({}, merge_result.status) + self.assertEquals({}, self.repo.status()) def test_merge_no_fastforward_no_conflicts(self): branch_head_hex = '03490f16b15a09913edb3a067a3dc67fbb8d41f1' @@ -333,10 +333,15 @@ class RepositoryTest_III(utils.RepoTestCaseForMerging): merge_result = self.repo.merge(branch_oid) self.assertFalse(merge_result.is_uptodate) self.assertFalse(merge_result.is_fastforward) - self.assertEquals(None, merge_result.fastforward_oid) # Asking twice to assure the reference counting is correct - self.assertEquals({'bye.txt': 1}, merge_result.status) - self.assertEquals({'bye.txt': 1}, merge_result.status) + self.assertEquals(None, merge_result.fastforward_oid) + self.assertEquals(None, merge_result.fastforward_oid) + self.assertEquals({'bye.txt': 1}, self.repo.status()) + self.assertEquals({'bye.txt': 1}, self.repo.status()) + # Checking the index works as expected + merge_result.index.remove('bye.txt') + merge_result.index.write() + self.assertEquals({'bye.txt': 128}, self.repo.status()) def test_merge_no_fastforward_conflicts(self): branch_head_hex = '1b2bae55ac95a4be3f8983b86cd579226d0eb247' @@ -344,10 +349,15 @@ class RepositoryTest_III(utils.RepoTestCaseForMerging): merge_result = self.repo.merge(branch_oid) self.assertFalse(merge_result.is_uptodate) self.assertFalse(merge_result.is_fastforward) - self.assertEquals(None, merge_result.fastforward_oid) # Asking twice to assure the reference counting is correct - self.assertEquals({'.gitignore': 132}, merge_result.status) - self.assertEquals({'.gitignore': 132}, merge_result.status) + self.assertEquals(None, merge_result.fastforward_oid) + self.assertEquals(None, merge_result.fastforward_oid) + self.assertEquals({'.gitignore': 132}, self.repo.status()) + self.assertEquals({'.gitignore': 132}, self.repo.status()) + # Checking the index works as expected + merge_result.index.add('.gitignore') + merge_result.index.write() + self.assertEquals({'.gitignore': 2}, self.repo.status()) def test_merge_invalid_hex(self): branch_head_hex = '12345678'