Commits

Marcin Kuzminski committed 5fba377

#590 Add GET flag that controls the way the diff are generated, for pull requests we want to use non-bundle based diffs,
That are far better for doing code reviews. The /compare url still uses bundle compare for full comparision including the incoming changesets.
- Fixed tests

Comments (0)

Files changed (5)

rhodecode/controllers/compare.py

 from rhodecode.model.db import Repository
 from rhodecode.model.pull_request import PullRequestModel
 from webob.exc import HTTPBadRequest
+from rhodecode.lib.utils2 import str2bool
 
 log = logging.getLogger(__name__)
 
         org_ref = (org_ref_type, org_ref)
         other_ref = (other_ref_type, other_ref)
         other_repo = request.GET.get('repo', org_repo)
+        bundle_compare = str2bool(request.GET.get('bundle', True))
 
         c.swap_url = h.url('compare_url', repo_name=other_repo,
               org_ref_type=other_ref[0], org_ref=other_ref[1],
               other_ref_type=org_ref[0], other_ref=org_ref[1],
-              repo=org_repo)
+              repo=org_repo, as_form=request.GET.get('as_form'),
+              bundle=bundle_compare)
 
         c.org_repo = org_repo = Repository.get_by_repo_name(org_repo)
         c.other_repo = other_repo = Repository.get_by_repo_name(other_repo)
         self.__get_cs_or_redirect(rev=other_ref, repo=other_repo, partial=partial)
 
         c.cs_ranges, discovery_data = PullRequestModel().get_compare_data(
-                                       org_repo, org_ref, other_repo, other_ref
-                                      )
+                                    org_repo, org_ref, other_repo, other_ref
+                                    )
 
         c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in
                                                    c.cs_ranges])
         if partial:
             return render('compare/compare_cs.html')
 
+        if not bundle_compare and c.cs_ranges:
+            # case we want a simple diff without incoming changesets, just
+            # for review purposes. Make the diff on the forked repo, with
+            # revision that is common ancestor
+            other_ref = ('rev', c.cs_ranges[-1].parents[0].raw_id)
+            other_repo = org_repo
+
         c.org_ref = org_ref[1]
         c.other_ref = other_ref[1]
-        # diff needs to have swapped org with other to generate proper diff
+
         _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref,
-                             discovery_data)
+                             discovery_data, bundle_compare=bundle_compare)
         diff_processor = diffs.DiffProcessor(_diff, format='gitdiff')
         _parsed = diff_processor.prepare()
 

rhodecode/controllers/pullrequests.py

         c.cs_ranges, discovery_data = PullRequestModel().get_compare_data(
                                        org_repo, org_ref, other_repo, other_ref
                                       )
+        if c.cs_ranges:
+            # case we want a simple diff without incoming changesets, just
+            # for review purposes. Make the diff on the forked repo, with
+            # revision that is common ancestor
+            other_ref = ('rev', c.cs_ranges[-1].parents[0].raw_id)
+            other_repo = org_repo
 
         c.statuses = org_repo.statuses([x.raw_id for x in c.cs_ranges])
         # defines that we need hidden inputs with changesets

rhodecode/lib/diffs.py

 import re
 import difflib
 import markupsafe
+import logging
 
 from itertools import tee, imap
 
 from rhodecode.lib.utils import make_ui
 from rhodecode.lib.utils2 import safe_unicode
 
+log = logging.getLogger(__name__)
+
 
 def wrap_to_table(str_):
     return '''<table class="code-difftable">
         self.bundlefilespos = {}
 
 
-def differ(org_repo, org_ref, other_repo, other_ref, discovery_data=None):
+def differ(org_repo, org_ref, other_repo, other_ref, discovery_data=None,
+           bundle_compare=False):
     """
     General differ between branches, bookmarks or separate but releated
     repositories
     org_ref = org_ref[1]
     other_ref = other_ref[1]
 
-    if org_repo != other_repo:
+    if org_repo != other_repo and bundle_compare:
 
         common, incoming, rheads = discovery_data
         other_repo_peer = localrepo.locallegacypeer(other_repo.local())
                                   node2=other_repo[other_ref].node(),
                                   opts=opts))
     else:
+        log.debug('running diff between %s@%s and %s@%s'
+                  % (org_repo, org_ref, other_repo, other_ref))
         return ''.join(patch.diff(org_repo, node1=org_ref, node2=other_ref,
                                   opts=opts))

rhodecode/templates/pullrequests/pullrequest.html

     	                 org_ref_type='org_ref_type', org_ref='org_ref',
                          other_ref_type='other_ref_type', other_ref='other_ref',
                          repo='other_repo',
-                         as_form=True)}";
+                         as_form=True, bundle=False)}";
 
       var select_refs = YUQ('#pull_request_form select.refs')
       var rev_data = {}; // gather the org/other ref and repo here

rhodecode/tests/functional/test_compare.py

                                     org_ref=rev1,
                                     other_ref_type="branch",
                                     other_ref=rev2,
-                                    repo=r1_name
+                                    repo=r1_name,
+                                    bundle=True,
                                     ))
 
         try:
                 cs=EmptyChangeset(alias='hg'), user=TEST_USER_ADMIN_LOGIN,
                 author=TEST_USER_ADMIN_LOGIN,
                 message='commit2',
+                content='line1-from-new-parent',
+                f_path='file2'
+            )
+            #compare !
+            rev1 = 'default'
+            rev2 = 'default'
+            response = self.app.get(url(controller='compare', action='index',
+                                        repo_name=r2_name,
+                                        org_ref_type="branch",
+                                        org_ref=rev1,
+                                        other_ref_type="branch",
+                                        other_ref=rev2,
+                                        repo=r1_name,
+                                        bundle=True,
+                                        ))
+
+            response.mustcontain('%s@%s -> %s@%s' % (r2_name, rev1, r1_name, rev2))
+            response.mustcontain("""<a href="#">file2</a>""")  # new commit from parent
+            response.mustcontain("""line1-from-new-parent""")
+            response.mustcontain("""file1-line1-from-fork""")
+            response.mustcontain("""file2-line1-from-fork""")
+            response.mustcontain("""file3-line1-from-fork""")
+        finally:
+            RepoModel().delete(r2_id)
+            RepoModel().delete(r1_id)
+
+    def test_org_repo_new_commits_after_forking_simple_diff(self):
+        self.log_user()
+
+        repo1 = RepoModel().create_repo(repo_name='one', repo_type='hg',
+                                        description='diff-test',
+                                        owner=TEST_USER_ADMIN_LOGIN)
+
+        Session().commit()
+        r1_id = repo1.repo_id
+        r1_name = repo1.repo_name
+
+        #commit something initially !
+        cs0 = ScmModel().create_node(
+            repo=repo1.scm_instance, repo_name=r1_name,
+            cs=EmptyChangeset(alias='hg'), user=TEST_USER_ADMIN_LOGIN,
+            author=TEST_USER_ADMIN_LOGIN,
+            message='commit1',
+            content='line1',
+            f_path='file1'
+        )
+        Session().commit()
+        self.assertEqual(repo1.scm_instance.revisions, [cs0.raw_id])
+        #fork the repo1
+        repo2 = RepoModel().create_repo(repo_name='one-fork', repo_type='hg',
+                                description='compare-test',
+                                clone_uri=repo1.repo_full_path,
+                                owner=TEST_USER_ADMIN_LOGIN, fork_of='one')
+        Session().commit()
+        self.assertEqual(repo2.scm_instance.revisions, [cs0.raw_id])
+        r2_id = repo2.repo_id
+        r2_name = repo2.repo_name
+
+        #make 3 new commits in fork
+        cs1 = ScmModel().create_node(
+            repo=repo2.scm_instance, repo_name=r2_name,
+            cs=repo2.scm_instance[-1], user=TEST_USER_ADMIN_LOGIN,
+            author=TEST_USER_ADMIN_LOGIN,
+            message='commit1-fork',
+            content='file1-line1-from-fork',
+            f_path='file1-fork'
+        )
+        cs2 = ScmModel().create_node(
+            repo=repo2.scm_instance, repo_name=r2_name,
+            cs=cs1, user=TEST_USER_ADMIN_LOGIN,
+            author=TEST_USER_ADMIN_LOGIN,
+            message='commit2-fork',
+            content='file2-line1-from-fork',
+            f_path='file2-fork'
+        )
+        cs3 = ScmModel().create_node(
+            repo=repo2.scm_instance, repo_name=r2_name,
+            cs=cs2, user=TEST_USER_ADMIN_LOGIN,
+            author=TEST_USER_ADMIN_LOGIN,
+            message='commit3-fork',
+            content='file3-line1-from-fork',
+            f_path='file3-fork'
+        )
+
+        #compare !
+        rev1 = 'default'
+        rev2 = 'default'
+        response = self.app.get(url(controller='compare', action='index',
+                                    repo_name=r2_name,
+                                    org_ref_type="branch",
+                                    org_ref=rev1,
+                                    other_ref_type="branch",
+                                    other_ref=rev2,
+                                    repo=r1_name,
+                                    bundle=False,
+                                    ))
+
+        try:
+            #response.mustcontain('%s@%s -> %s@%s' % (r2_name, rev1, r1_name, rev2))
+
+            #add new commit into parent !
+            cs0 = ScmModel().create_node(
+                repo=repo1.scm_instance, repo_name=r1_name,
+                cs=EmptyChangeset(alias='hg'), user=TEST_USER_ADMIN_LOGIN,
+                author=TEST_USER_ADMIN_LOGIN,
+                message='commit2',
                 content='line1',
                 f_path='file2'
             )
                                         org_ref=rev1,
                                         other_ref_type="branch",
                                         other_ref=rev2,
-                                        repo=r1_name
+                                        repo=r1_name,
+                                        bundle=False
                                         ))
-
+            rev2 = cs0.parents[0].raw_id
             response.mustcontain('%s@%s -> %s@%s' % (r2_name, rev1, r1_name, rev2))
             response.mustcontain("""file1-line1-from-fork""")
             response.mustcontain("""file2-line1-from-fork""")
             response.mustcontain("""file3-line1-from-fork""")
+            self.assertFalse("""<a href="#">file2</a>""" in response.body)  # new commit from parent
+            self.assertFalse("""line1-from-new-parent"""  in response.body)
         finally:
             RepoModel().delete(r2_id)
-            RepoModel().delete(r1_id)
+            RepoModel().delete(r1_id)