← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~cjwatson/turnip/merge-conflicts into lp:turnip

 

Colin Watson has proposed merging lp:~cjwatson/turnip/merge-conflicts into lp:turnip.

Commit message:
Produce useful merge diffs for conflicts, and add a 'conflicts' key to the returned dictionary.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/turnip/merge-conflicts/+merge/257339

Produce useful merge diffs for conflicts, and add a 'conflicts' key to the returned dictionary.

This requires some cherry-picks from pygit2 0.22.1, which are in ppa:launchpad/ubuntu/ppa.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/turnip/merge-conflicts into lp:turnip.
=== modified file 'setup.py'
--- setup.py	2015-04-08 11:47:39 +0000
+++ setup.py	2015-04-24 09:38:41 +0000
@@ -17,6 +17,7 @@
 requires = [
     'cornice',
     'lazr.sshserver',
+    # Should be 0.22.1 once released; for the time being we carry cherry-picks.
     'pygit2>=0.22.0,<0.23.0',
     'PyYAML',
     'Twisted',

=== modified file 'turnip/api/store.py'
--- turnip/api/store.py	2015-04-16 21:47:08 +0000
+++ turnip/api/store.py	2015-04-24 09:38:41 +0000
@@ -7,12 +7,14 @@
 import urlparse
 
 from pygit2 import (
+    clone_repository,
     GitError,
+    GIT_FILEMODE_BLOB,
     GIT_OBJ_BLOB,
     GIT_OBJ_COMMIT,
     GIT_OBJ_TREE,
     GIT_OBJ_TAG,
-    clone_repository,
+    IndexEntry,
     init_repository,
     Repository,
     )
@@ -139,11 +141,23 @@
     """
     repo = open_repo(repo_path)
     merged_index = repo.merge_commits(sha1_base, sha1_head)
+    conflicts = set()
+    if merged_index.conflicts is not None:
+        for conflict in list(merged_index.conflicts):
+            path = [entry for entry in conflict if entry is not None][0].path
+            conflicts.add(path)
+            try:
+                merged_file = repo.merge_file_from_index(*conflict)
+            except Exception:
+                continue
+            blob_oid = repo.create_blob(merged_file)
+            merged_index.add(IndexEntry(path, blob_oid, GIT_FILEMODE_BLOB))
+            del merged_index.conflicts[path]
     diff = merged_index.diff_to_tree(
         repo[sha1_base].tree, context_lines=context_lines).patch
     shas = [sha1_base, sha1_head]
     commits = [get_commit(repo_path, sha, repo) for sha in shas]
-    diff = {'commits': commits, 'patch': diff}
+    diff = {'commits': commits, 'patch': diff, 'conflicts': sorted(conflicts)}
     return diff
 
 

=== modified file 'turnip/api/tests/test_api.py'
--- turnip/api/tests/test_api.py	2015-04-16 21:47:08 +0000
+++ turnip/api/tests/test_api.py	2015-04-24 09:38:41 +0000
@@ -3,6 +3,7 @@
 from __future__ import print_function
 
 import os
+from textwrap import dedent
 import unittest
 import uuid
 
@@ -253,6 +254,25 @@
         self.assertIn('-baz', resp.json_body['patch'])
         self.assertIn('+bar', resp.json_body['patch'])
         self.assertNotIn('foo', resp.json_body['patch'])
+        self.assertEqual([], resp.json_body['conflicts'])
+
+    def test_repo_diff_merge_with_conflicts(self):
+        """Ensure that compare-merge returns conflicts information."""
+        repo = RepoFactory(self.repo_store)
+        c1 = repo.add_commit('foo\n', 'blah.txt')
+        c2_left = repo.add_commit('foo\nbar\n', 'blah.txt', parents=[c1])
+        c2_right = repo.add_commit('foo\nbaz\n', 'blah.txt', parents=[c1])
+
+        resp = self.app.get('/repo/{}/compare-merge/{}/{}'.format(
+            self.repo_path, c2_left, c2_right))
+        self.assertIn(dedent("""\
+            +<<<<<<< blah.txt
+             bar
+            +=======
+            +baz
+            +>>>>>>> blah.txt
+            """), resp.json_body['patch'])
+        self.assertEqual(['blah.txt'], resp.json_body['conflicts'])
 
     def test_repo_get_commit(self):
         factory = RepoFactory(self.repo_store)


Follow ups