diff --git a/README.rst b/README.rst index e57556e43..47e6ff2a5 100644 --- a/README.rst +++ b/README.rst @@ -99,7 +99,7 @@ Changelog - New ``Repository.state_cleanup()`` `#386 `_ -- New ``Index.has_conflicts`` and ``Index.conflicts`` #345 +- New ```Index.conflicts`` `#345 `_ `#389 `_ diff --git a/pygit2/index.py b/pygit2/index.py index 227957b13..8e2da1fc9 100644 --- a/pygit2/index.py +++ b/pygit2/index.py @@ -203,12 +203,6 @@ def add(self, path_or_entry): check_error(err, True) - @property - def has_conflicts(self): - """Whether this Index contains conflict information - """ - return C.git_index_has_conflicts(self._index) != 0 - def diff_to_workdir(self, flags=0, context_lines=3, interhunk_lines=0): """diff_to_workdir(flags=0, context_lines=3, interhunk_lines=0) -> Diff @@ -290,11 +284,20 @@ def diff_to_tree(self, tree, flags=0, context_lines=3, interhunk_lines=0): return Diff.from_c(bytes(ffi.buffer(cdiff)[:]), self._repo) + + # + # Conflicts + # + _conflicts = None + @property def conflicts(self): """A collection of conflict information - This presents a mapping interface with the paths as keys. You + If there are no conflicts None is returned. Otherwise return an object + that represents the conflicts in the index. + + This object presents a mapping interface with the paths as keys. You can use the ``del`` operator to remove a conflict form the Index. Each conflict is made up of three elements. Access or iteration @@ -306,7 +309,11 @@ def conflicts(self): These elements may be None depending on which sides exist for the particular conflict. """ - if not hasattr(self, '_conflicts'): + if not C.git_index_has_conflicts(self._index): + self._conflicts = None + return None + + if self._conflicts is None: self._conflicts = ConflictCollection(self) return self._conflicts diff --git a/test/test_merge.py b/test/test_merge.py index 2bebb5d33..b2a2574d5 100644 --- a/test/test_merge.py +++ b/test/test_merge.py @@ -81,7 +81,7 @@ def test_merge_no_fastforward_conflicts(self): self.assertFalse(analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) self.repo.merge(branch_id) - self.assertTrue(self.repo.index.has_conflicts) + self.assertTrue(self.repo.index.conflicts is not None) status = pygit2.GIT_STATUS_WT_NEW | pygit2.GIT_STATUS_INDEX_DELETED # Asking twice to assure the reference counting is correct self.assertEqual({'.gitignore': status}, self.repo.status()) @@ -114,7 +114,7 @@ def test_merge_no_fastforward_conflicts(self): self.assertFalse(analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) self.repo.merge(branch_id) - self.assertTrue(self.repo.index.has_conflicts) + self.assertTrue(self.repo.index.conflicts is not None) self.assertRaises(KeyError, self.repo.index.conflicts.__getitem__, 'some-file') ancestor, ours, theirs = self.repo.index.conflicts['.gitignore'] self.assertEqual(None, ancestor) @@ -126,13 +126,18 @@ def test_merge_no_fastforward_conflicts(self): # Checking the index works as expected self.repo.index.add('.gitignore') self.repo.index.write() - self.assertRaises(KeyError, self.repo.index.conflicts.__getitem__, '.gitignore') + self.assertTrue(self.repo.index.conflicts is None) def test_merge_remove_conflicts(self): other_branch_tip = '1b2bae55ac95a4be3f8983b86cd579226d0eb247' self.repo.merge(other_branch_tip) idx = self.repo.index - self.assertTrue(idx.has_conflicts) - self.assertRaises(KeyError, idx.conflicts.__delitem__, 'some-file') + conflicts = idx.conflicts + self.assertTrue(conflicts is not None) + try: + conflicts['.gitignore'] + except KeyError: + self.fail("conflicts['.gitignore'] raised KeyError unexpectedly") del idx.conflicts['.gitignore'] - self.assertFalse(idx.has_conflicts) + self.assertRaises(KeyError, conflicts.__getitem__, '.gitignore') + self.assertTrue(idx.conflicts is None)