# HG changeset patch # User Marcin Kuzminski # Date 2018-10-15 10:44:36 # Node ID ddd1ae7b09af52c26805612097b53e71e45f6b99 # Parent 5d8c4f9bece0ff852bd80596566dd30ec44f53c4 pull-requests: allow to show range diff in pr view diff --git a/rhodecode/apps/_base/__init__.py b/rhodecode/apps/_base/__init__.py --- a/rhodecode/apps/_base/__init__.py +++ b/rhodecode/apps/_base/__init__.py @@ -303,7 +303,8 @@ class PathFilter(object): def render_patchset_filtered(self, diffset, patchset, source_ref=None, target_ref=None): filtered_patchset, has_hidden_changes = self.filter_patchset(patchset) - result = diffset.render_patchset(filtered_patchset, source_ref=source_ref, target_ref=target_ref) + result = diffset.render_patchset( + filtered_patchset, source_ref=source_ref, target_ref=target_ref) result.has_hidden_changes = has_hidden_changes return result diff --git a/rhodecode/apps/repository/tests/test_repo_commit_comments.py b/rhodecode/apps/repository/tests/test_repo_commit_comments.py --- a/rhodecode/apps/repository/tests/test_repo_commit_comments.py +++ b/rhodecode/apps/repository/tests/test_repo_commit_comments.py @@ -135,12 +135,18 @@ class TestRepoCommitCommentsView(TestCon if backend.alias == 'svn': response.mustcontain( '''data-f-path="vcs/commands/summary.py" ''' - '''id="a_c--ad05457a43f8"''' + '''id="a_c-300-ad05457a43f8"''' ) - else: + if backend.alias == 'git': response.mustcontain( '''data-f-path="vcs/backends/hg.py" ''' - '''id="a_c--9c390eb52cd6"''' + '''id="a_c-883e775e89ea-9c390eb52cd6"''' + ) + + if backend.alias == 'hg': + response.mustcontain( + '''data-f-path="vcs/backends/hg.py" ''' + '''id="a_c-e58d85a3973b-9c390eb52cd6"''' ) assert Notification.query().count() == 1 diff --git a/rhodecode/apps/repository/tests/test_repo_compare.py b/rhodecode/apps/repository/tests/test_repo_compare.py --- a/rhodecode/apps/repository/tests/test_repo_compare.py +++ b/rhodecode/apps/repository/tests/test_repo_compare.py @@ -104,13 +104,11 @@ class TestCompareView(object): # Comparing the revisions response = self.app.get( route_path('repo_compare', - repo_name=origin.repo_name, - source_ref_type="rev", - source_ref=commit3.raw_id, - target_ref_type="rev", - target_ref=commit4.raw_id, - params=dict(merge='1', target_repo=fork.repo_name) - )) + repo_name=origin.repo_name, + source_ref_type="rev", source_ref=commit3.raw_id, + target_ref_type="rev", target_ref=commit4.raw_id, + params=dict(merge='1', target_repo=fork.repo_name) + )) compare_page = ComparePage(response) compare_page.contains_commits([commit4]) @@ -142,13 +140,11 @@ class TestCompareView(object): response = self.app.get( route_path('repo_compare', - repo_name=repo1.repo_name, - source_ref_type="branch", - source_ref=commit_id2, - target_ref_type="branch", - target_ref=commit_id1, - params=dict(merge='1', target_repo=repo2.repo_name) - )) + repo_name=repo1.repo_name, + source_ref_type="branch", source_ref=commit_id2, + target_ref_type="branch", target_ref=commit_id1, + params=dict(merge='1', target_repo=repo2.repo_name) + )) response.mustcontain('%s@%s' % (repo1.repo_name, commit_id2)) response.mustcontain('%s@%s' % (repo2.repo_name, commit_id1)) @@ -156,9 +152,9 @@ class TestCompareView(object): compare_page = ComparePage(response) compare_page.contains_change_summary(1, 2, 0) compare_page.contains_commits([commit1, commit2]) - compare_page.contains_file_links_and_anchors([ - ('file1', 'a_c--826e8142e6ba'), - ]) + + anchor = 'a_c-{}-826e8142e6ba'.format(commit0.short_id) + compare_page.contains_file_links_and_anchors([('file1', anchor), ]) # Swap is removed when comparing branches since it's a PR feature and # it is then a preview mode @@ -199,13 +195,11 @@ class TestCompareView(object): response = self.app.get( route_path('repo_compare', - repo_name=repo1.repo_name, - source_ref_type="branch", - source_ref=commit_id2, - target_ref_type="branch", - target_ref=commit_id1, - params=dict(merge='1', target_repo=repo2.repo_name), - )) + repo_name=repo1.repo_name, + source_ref_type="branch", source_ref=commit_id2, + target_ref_type="branch", target_ref=commit_id1, + params=dict(merge='1', target_repo=repo2.repo_name), + )) response.mustcontain('%s@%s' % (repo1.repo_name, commit_id2)) response.mustcontain('%s@%s' % (repo2.repo_name, commit_id1)) @@ -213,9 +207,8 @@ class TestCompareView(object): compare_page = ComparePage(response) compare_page.contains_change_summary(1, 2, 0) compare_page.contains_commits([commit1, commit2]) - compare_page.contains_file_links_and_anchors([ - ('file1', 'a_c--826e8142e6ba'), - ]) + anchor = 'a_c-{}-826e8142e6ba'.format(commit0.short_id) + compare_page.contains_file_links_and_anchors([('file1', anchor), ]) # Swap is removed when comparing branches since it's a PR feature and # it is then a preview mode @@ -230,13 +223,11 @@ class TestCompareView(object): response = self.app.get( route_path('repo_compare', - repo_name=orig.repo_name, - source_ref_type="rev", - source_ref="tip", - target_ref_type="rev", - target_ref="tip", - params=dict(merge='1', target_repo=fork.repo_name), - ), + repo_name=orig.repo_name, + source_ref_type="rev", source_ref="tip", + target_ref_type="rev", target_ref="tip", + params=dict(merge='1', target_repo=fork.repo_name), + ), status=302) response = response.follow() response.mustcontain("Repositories unrelated.") @@ -289,14 +280,12 @@ class TestCompareView(object): response = self.app.get( route_path('repo_compare', - repo_name=repo2.repo_name, - source_ref_type="rev", - # parent of commit2, in target repo2 - source_ref=commit1.raw_id, - target_ref_type="rev", - target_ref=commit4.raw_id, - params=dict(merge='1', target_repo=repo1.repo_name), - )) + repo_name=repo2.repo_name, + # parent of commit2, in target repo2 + source_ref_type="rev", source_ref=commit1.raw_id, + target_ref_type="rev", target_ref=commit4.raw_id, + params=dict(merge='1', target_repo=repo1.repo_name), + )) response.mustcontain('%s@%s' % (repo2.repo_name, commit1.short_id)) response.mustcontain('%s@%s' % (repo1.repo_name, commit4.short_id)) @@ -304,9 +293,8 @@ class TestCompareView(object): compare_page = ComparePage(response) compare_page.contains_change_summary(1, 3, 0) compare_page.contains_commits([commit2, commit3, commit4]) - compare_page.contains_file_links_and_anchors([ - ('file1', 'a_c--826e8142e6ba'), - ]) + anchor = 'a_c-{}-826e8142e6ba'.format(commit1.short_id) + compare_page.contains_file_links_and_anchors([('file1', anchor),]) @pytest.mark.xfail_backends("svn") def test_compare_cherry_pick_commits_from_top(self, backend): @@ -355,14 +343,11 @@ class TestCompareView(object): response = self.app.get( route_path('repo_compare', - repo_name=repo1.repo_name, - source_ref_type="rev", - # parent of commit3, not in source repo2 - source_ref=commit2.raw_id, - target_ref_type="rev", - target_ref=commit5.raw_id, - params=dict(merge='1'), - )) + repo_name=repo1.repo_name, + # parent of commit3, not in source repo2 + source_ref_type="rev", source_ref=commit2.raw_id, + target_ref_type="rev", target_ref=commit5.raw_id, + params=dict(merge='1'),)) response.mustcontain('%s@%s' % (repo1.repo_name, commit2.short_id)) response.mustcontain('%s@%s' % (repo1.repo_name, commit5.short_id)) @@ -372,9 +357,8 @@ class TestCompareView(object): compare_page.contains_commits([commit3, commit4, commit5]) # files - compare_page.contains_file_links_and_anchors([ - ('file1', 'a_c--826e8142e6ba'), - ]) + anchor = 'a_c-{}-826e8142e6ba'.format(commit2.short_id) + compare_page.contains_file_links_and_anchors([('file1', anchor),]) @pytest.mark.xfail_backends("svn") def test_compare_remote_branches(self, backend): @@ -382,17 +366,17 @@ class TestCompareView(object): repo2 = backend.create_fork() commit_id1 = repo1.get_commit(commit_idx=3).raw_id + commit_id1_short = repo1.get_commit(commit_idx=3).short_id commit_id2 = repo1.get_commit(commit_idx=6).raw_id + commit_id2_short = repo1.get_commit(commit_idx=6).short_id response = self.app.get( route_path('repo_compare', - repo_name=repo1.repo_name, - source_ref_type="rev", - source_ref=commit_id1, - target_ref_type="rev", - target_ref=commit_id2, - params=dict(merge='1', target_repo=repo2.repo_name), - )) + repo_name=repo1.repo_name, + source_ref_type="rev", source_ref=commit_id1, + target_ref_type="rev", target_ref=commit_id2, + params=dict(merge='1', target_repo=repo2.repo_name), + )) response.mustcontain('%s@%s' % (repo1.repo_name, commit_id1)) response.mustcontain('%s@%s' % (repo2.repo_name, commit_id2)) @@ -405,9 +389,9 @@ class TestCompareView(object): # files compare_page.contains_file_links_and_anchors([ - ('vcs/backends/hg.py', 'a_c--9c390eb52cd6'), - ('vcs/backends/__init__.py', 'a_c--41b41c1f2796'), - ('vcs/backends/base.py', 'a_c--2f574d260608'), + ('vcs/backends/hg.py', 'a_c-{}-9c390eb52cd6'.format(commit_id2_short)), + ('vcs/backends/__init__.py', 'a_c-{}-41b41c1f2796'.format(commit_id1_short)), + ('vcs/backends/base.py', 'a_c-{}-2f574d260608'.format(commit_id1_short)), ]) @pytest.mark.xfail_backends("svn") @@ -451,13 +435,11 @@ class TestCompareView(object): response = self.app.get( route_path('repo_compare', - repo_name=r2_name, - source_ref_type="branch", - source_ref=commit_id1, - target_ref_type="branch", - target_ref=commit_id2, - params=dict(merge='1', target_repo=r1_name), - )) + repo_name=r2_name, + source_ref_type="branch", source_ref=commit_id1, + target_ref_type="branch", target_ref=commit_id2, + params=dict(merge='1', target_repo=r1_name), + )) response.mustcontain('%s@%s' % (r2_name, commit_id1)) response.mustcontain('%s@%s' % (r1_name, commit_id2)) @@ -472,13 +454,11 @@ class TestCompareView(object): # compare ! response = self.app.get( route_path('repo_compare', - repo_name=r2_name, - source_ref_type="branch", - source_ref=commit_id1, - target_ref_type="branch", - target_ref=commit_id2, - params=dict(merge='1', target_repo=r1_name), - )) + repo_name=r2_name, + source_ref_type="branch", source_ref=commit_id1, + target_ref_type="branch", target_ref=commit_id2, + params=dict(merge='1', target_repo=r1_name), + )) response.mustcontain('%s@%s' % (r2_name, commit_id1)) response.mustcontain('%s@%s' % (r1_name, commit_id2)) @@ -495,14 +475,12 @@ class TestCompareView(object): response = self.app.get( route_path('repo_compare', - repo_name=backend.repo_name, - source_ref_type="rev", - source_ref=commit0.raw_id, - target_ref_type="rev", - target_ref=commit1.raw_id, - params=dict(merge='1') - ), - extra_environ=xhr_header,) + repo_name=backend.repo_name, + source_ref_type="rev", source_ref=commit0.raw_id, + target_ref_type="rev", target_ref=commit1.raw_id, + params=dict(merge='1') + ), + extra_environ=xhr_header, ) # outgoing commits between those commits compare_page = ComparePage(response) @@ -514,13 +492,11 @@ class TestCompareView(object): response = self.app.get( route_path('repo_compare', - repo_name=badrepo, - source_ref_type="rev", - source_ref='tip', - target_ref_type="rev", - target_ref='tip', - params=dict(merge='1', target_repo=repo.repo_name) - ), + repo_name=badrepo, + source_ref_type="rev", source_ref='tip', + target_ref_type="rev", target_ref='tip', + params=dict(merge='1', target_repo=repo.repo_name) + ), status=404) def test_errors_when_comparing_unknown_target_repo(self, backend): @@ -529,13 +505,11 @@ class TestCompareView(object): response = self.app.get( route_path('repo_compare', - repo_name=repo.repo_name, - source_ref_type="rev", - source_ref='tip', - target_ref_type="rev", - target_ref='tip', - params=dict(merge='1', target_repo=badrepo), - ), + repo_name=repo.repo_name, + source_ref_type="rev", source_ref='tip', + target_ref_type="rev", target_ref='tip', + params=dict(merge='1', target_repo=badrepo), + ), status=302) redirected = response.follow() redirected.mustcontain( @@ -547,12 +521,10 @@ class TestCompareView(object): response = self.app.get( route_path('repo_compare', - repo_name=backend_stub.repo_name, - source_ref_type="rev", - source_ref=commit0.raw_id, - target_ref_type="rev", - target_ref=commit1.raw_id, - )) + repo_name=backend_stub.repo_name, + source_ref_type="rev", source_ref=commit0.raw_id, + target_ref_type="rev", target_ref=commit1.raw_id, + )) # outgoing commits between those commits compare_page = ComparePage(response) @@ -575,13 +547,11 @@ class TestCompareView(object): response = self.app.get( route_path('repo_compare', - repo_name=orig.repo_name, - source_ref_type="rev", - source_ref="tip", - target_ref_type="rev", - target_ref="tip", - params=dict(merge='1', target_repo=fork.repo_name), - ), + repo_name=orig.repo_name, + source_ref_type="rev", source_ref="tip", + target_ref_type="rev", target_ref="tip", + params=dict(merge='1', target_repo=fork.repo_name), + ), status=302) assert_session_flash( @@ -597,13 +567,13 @@ class TestCompareControllerSvn(object): commit_id = repo.get_commit(commit_idx=-1).raw_id response = app.get( route_path('repo_compare', - repo_name=repo.repo_name, - source_ref_type="tag", - source_ref="%s@%s" % ('tags/v0.1', commit_id), - target_ref_type="tag", - target_ref="%s@%s" % ('tags/v0.2', commit_id), - params=dict(merge='1'), - ), + repo_name=repo.repo_name, + source_ref_type="tag", + source_ref="%s@%s" % ('tags/v0.1', commit_id), + target_ref_type="tag", + target_ref="%s@%s" % ('tags/v0.2', commit_id), + params=dict(merge='1'), + ), status=200) # Expecting no commits, since both paths are at the same revision @@ -620,13 +590,13 @@ class TestCompareControllerSvn(object): target_id = repo.get_commit(commit_idx=-1).raw_id response = app.get( route_path('repo_compare', - repo_name=repo.repo_name, - source_ref_type="tag", - source_ref="%s@%s" % ('tags/v0.1', source_id), - target_ref_type="tag", - target_ref="%s@%s" % ('tags/v0.2', target_id), - params=dict(merge='1') - ), + repo_name=repo.repo_name, + source_ref_type="tag", + source_ref="%s@%s" % ('tags/v0.1', source_id), + target_ref_type="tag", + target_ref="%s@%s" % ('tags/v0.2', target_id), + params=dict(merge='1') + ), status=200) # It should show commits @@ -694,4 +664,3 @@ class ComparePage(AssertResponse): def target_source_are_enabled(self): response = self.response response.mustcontain("var enable_fields = true;") - diff --git a/rhodecode/apps/repository/tests/test_repo_compare_local.py b/rhodecode/apps/repository/tests/test_repo_compare_local.py --- a/rhodecode/apps/repository/tests/test_repo_compare_local.py +++ b/rhodecode/apps/repository/tests/test_repo_compare_local.py @@ -47,10 +47,8 @@ class TestCompareView(object): route_path( 'repo_compare', repo_name=backend.repo_name, - source_ref_type="tag", - source_ref=tag1, - target_ref_type="tag", - target_ref=tag2), + source_ref_type="tag", source_ref=tag1, + target_ref_type="tag", target_ref=tag2), status=200) response.mustcontain('%s@%s' % (backend.repo_name, tag1)) @@ -69,18 +67,28 @@ class TestCompareView(object): compare_page.contains_commits(commits) # files diff + short_id = short_id_new = '' + if backend.alias == 'git': + short_id = '5a3a8fb00555' + short_id_new = '0ba5f8a46600' + if backend.alias == 'hg': + short_id = '17544fbfcd33' + short_id_new = 'a7e60bff65d5' + compare_page.contains_file_links_and_anchors([ - ('docs/api/utils/index.rst', 'a_c--1c5cf9e91c12'), - ('test_and_report.sh', 'a_c--e3305437df55'), - ('.hgignore', 'a_c--c8e92ef85cd1'), - ('.hgtags', 'a_c--6e08b694d687'), - ('docs/api/index.rst', 'a_c--2c14b00f3393'), - ('vcs/__init__.py', 'a_c--430ccbc82bdf'), - ('vcs/backends/hg.py', 'a_c--9c390eb52cd6'), - ('vcs/utils/__init__.py', 'a_c--ebb592c595c0'), - ('vcs/utils/annotate.py', 'a_c--7abc741b5052'), - ('vcs/utils/diffs.py', 'a_c--2ef0ef106c56'), - ('vcs/utils/lazy.py', 'a_c--3150cb87d4b7'), + # modified + ('docs/api/utils/index.rst', 'a_c-{}-1c5cf9e91c12'.format(short_id)), + ('test_and_report.sh', 'a_c-{}-e3305437df55'.format(short_id)), + # added + ('.hgignore', 'a_c-{}-c8e92ef85cd1'.format(short_id_new)), + ('.hgtags', 'a_c-{}-6e08b694d687'.format(short_id_new)), + ('docs/api/index.rst', 'a_c-{}-2c14b00f3393'.format(short_id_new)), + ('vcs/__init__.py', 'a_c-{}-430ccbc82bdf'.format(short_id_new)), + ('vcs/backends/hg.py', 'a_c-{}-9c390eb52cd6'.format(short_id_new)), + ('vcs/utils/__init__.py', 'a_c-{}-ebb592c595c0'.format(short_id_new)), + ('vcs/utils/annotate.py', 'a_c-{}-7abc741b5052'.format(short_id_new)), + ('vcs/utils/diffs.py', 'a_c-{}-2ef0ef106c56'.format(short_id_new)), + ('vcs/utils/lazy.py', 'a_c-{}-3150cb87d4b7'.format(short_id_new)), ]) @pytest.mark.xfail_backends("svn", msg="Depends on branch and tag support") @@ -104,12 +112,10 @@ class TestCompareView(object): response = self.app.get( route_path( - 'repo_compare', - repo_name=backend.repo_name, - source_ref_type='branch', - source_ref=data['branch'], - target_ref_type="tag", - target_ref=data['tag'], + 'repo_compare', + repo_name=backend.repo_name, + source_ref_type='branch', source_ref=data['branch'], + target_ref_type="tag", target_ref=data['tag'], )) response.mustcontain('%s@%s' % (backend.repo_name, data['branch'])) @@ -121,12 +127,10 @@ class TestCompareView(object): head_id = backend.default_head_id response = self.app.get( route_path( - 'repo_compare', - repo_name=backend.repo_name, - source_ref_type="branch", - source_ref=head_id, - target_ref_type="branch", - target_ref=head_id, + 'repo_compare', + repo_name=backend.repo_name, + source_ref_type="branch", source_ref=head_id, + target_ref_type="branch", target_ref=head_id, )) response.mustcontain('%s@%s' % (backend.repo_name, head_id)) @@ -138,16 +142,16 @@ class TestCompareView(object): def test_compare_commits(self, backend): repo = backend.repo commit1 = repo.get_commit(commit_idx=0) + commit1_short_id = commit1.short_id commit2 = repo.get_commit(commit_idx=1) + commit2_short_id = commit2.short_id response = self.app.get( route_path( - 'repo_compare', - repo_name=backend.repo_name, - source_ref_type="rev", - source_ref=commit1.raw_id, - target_ref_type="rev", - target_ref=commit2.raw_id, + 'repo_compare', + repo_name=backend.repo_name, + source_ref_type="rev", source_ref=commit1.raw_id, + target_ref_type="rev", target_ref=commit2.raw_id, )) response.mustcontain('%s@%s' % (backend.repo_name, commit1.raw_id)) response.mustcontain('%s@%s' % (backend.repo_name, commit2.raw_id)) @@ -158,6 +162,6 @@ class TestCompareView(object): # outgoing commits between those commits compare_page.contains_commits([commit2]) - compare_page.contains_file_links_and_anchors([ - ('.hgignore', 'a_c--c8e92ef85cd1'), - ]) + anchor = 'a_c-{}-c8e92ef85cd1'.format(commit2_short_id) + response.mustcontain(anchor) + compare_page.contains_file_links_and_anchors([('.hgignore', anchor),]) diff --git a/rhodecode/apps/repository/tests/test_repo_pullrequests.py b/rhodecode/apps/repository/tests/test_repo_pullrequests.py --- a/rhodecode/apps/repository/tests/test_repo_pullrequests.py +++ b/rhodecode/apps/repository/tests/test_repo_pullrequests.py @@ -81,20 +81,21 @@ class TestPullrequestsView(object): repo = backend.repo self.app.get( - route_path('pullrequest_new', - repo_name=repo.repo_name, - commit=repo.get_commit().raw_id), + route_path('pullrequest_new', repo_name=repo.repo_name, + commit=repo.get_commit().raw_id), status=200) @pytest.mark.parametrize('pr_merge_enabled', [True, False]) - def test_show(self, pr_util, pr_merge_enabled): + @pytest.mark.parametrize('range_diff', ["0", "1"]) + def test_show(self, pr_util, pr_merge_enabled, range_diff): pull_request = pr_util.create_pull_request( mergeable=pr_merge_enabled, enable_notifications=False) response = self.app.get(route_path( 'pullrequest_show', repo_name=pull_request.target_repo.scm_instance().name, - pull_request_id=pull_request.pull_request_id)) + pull_request_id=pull_request.pull_request_id, + params={'range-diff': range_diff})) for commit_id in pull_request.revisions: response.mustcontain(commit_id) @@ -105,9 +106,13 @@ class TestPullrequestsView(object): assert target_clone_url in response assert 'class="pull-request-merge"' in response - assert ( - 'Server-side pull request merging is disabled.' - in response) != pr_merge_enabled + if pr_merge_enabled: + response.mustcontain('Pull request reviewer approval is pending') + else: + response.mustcontain('Server-side pull request merging is disabled.') + + if range_diff == "1": + response.mustcontain('Turn off: Show the diff as commit range') def test_close_status_visibility(self, pr_util, user_util, csrf_token): # Logout diff --git a/rhodecode/apps/repository/views/repo_commits.py b/rhodecode/apps/repository/views/repo_commits.py --- a/rhodecode/apps/repository/views/repo_commits.py +++ b/rhodecode/apps/repository/views/repo_commits.py @@ -245,7 +245,7 @@ class RepoCommitsView(RepoAppView): c.changes[commit.raw_id] = [] commit2 = commit - commit1 = commit.parents[0] if commit.parents else EmptyCommit() + commit1 = commit.first_parent if method == 'show': inline_comments = CommentsModel().get_inline_comments( diff --git a/rhodecode/apps/repository/views/repo_pull_requests.py b/rhodecode/apps/repository/views/repo_pull_requests.py --- a/rhodecode/apps/repository/views/repo_pull_requests.py +++ b/rhodecode/apps/repository/views/repo_pull_requests.py @@ -138,6 +138,13 @@ class RepoPullRequestsView(RepoAppView, }) return data + def get_recache_flag(self): + for flag_name in ['force_recache', 'force-recache', 'no-cache']: + flag_val = self.request.GET.get(flag_name) + if str2bool(flag_val): + return True + return False + @LoginRequired() @HasRepoPermissionAnyDecorator( 'repository.read', 'repository.write', 'repository.admin') @@ -234,6 +241,30 @@ class RepoPullRequestsView(RepoAppView, return diffset + def _get_range_diffset(self, source_scm, source_repo, + commit1, commit2, diff_limit, file_limit, + fulldiff, ign_whitespace_lcl, context_lcl): + vcs_diff = source_scm.get_diff( + commit1, commit2, + ignore_whitespace=ign_whitespace_lcl, + context=context_lcl) + + diff_processor = diffs.DiffProcessor( + vcs_diff, format='newdiff', diff_limit=diff_limit, + file_limit=file_limit, show_full_diff=fulldiff) + + _parsed = diff_processor.prepare() + + diffset = codeblocks.DiffSet( + repo_name=source_repo.repo_name, + source_node_getter=codeblocks.diffset_node_getter(commit1), + target_node_getter=codeblocks.diffset_node_getter(commit2)) + + diffset = self.path_filter.render_patchset_filtered( + diffset, _parsed, commit1.raw_id, commit2.raw_id) + + return diffset + @LoginRequired() @HasRepoPermissionAnyDecorator( 'repository.read', 'repository.write', 'repository.admin') @@ -265,6 +296,9 @@ class RepoPullRequestsView(RepoAppView, pull_request_id=pull_request_id)) versions = pull_request_display_obj.versions() + # used to store per-commit range diffs + c.changes = collections.OrderedDict() + c.range_diff_on = self.request.GET.get('range-diff') == "1" c.at_version = at_version c.at_version_num = (at_version @@ -453,14 +487,13 @@ class RepoPullRequestsView(RepoAppView, version_normalized = version or 'latest' from_version_normalized = from_version or 'latest' - cache_path = self.rhodecode_vcs_repo.get_create_shadow_cache_pr_path( - target_repo) + cache_path = self.rhodecode_vcs_repo.get_create_shadow_cache_pr_path(target_repo) cache_file_path = diff_cache_exist( cache_path, 'pull_request', pull_request_id, version_normalized, from_version_normalized, source_ref_id, target_ref_id, c.fulldiff) caching_enabled = self._is_diff_cache_enabled(c.target_repo) - force_recache = str2bool(self.request.GET.get('force_recache')) + force_recache = self.get_recache_flag() cached_diff = None if caching_enabled: @@ -471,7 +504,8 @@ class RepoPullRequestsView(RepoAppView, and len(cached_diff.get('commits', [])) == 5 and cached_diff.get('commits')[0] and cached_diff.get('commits')[3]) - if not force_recache and has_proper_commit_cache: + + if not force_recache and not c.range_diff_on and has_proper_commit_cache: diff_commit_cache = \ (ancestor_commit, commit_cache, missing_requirements, source_commit, target_commit) = cached_diff['commits'] @@ -546,8 +580,41 @@ class RepoPullRequestsView(RepoAppView, c.deleted_files_comments[fname]['stats'] = 0 c.deleted_files_comments[fname]['comments'] = list() for lno, comments in per_line_comments.items(): - c.deleted_files_comments[fname]['comments'].extend( - comments) + c.deleted_files_comments[fname]['comments'].extend(comments) + + # maybe calculate the range diff + if c.range_diff_on: + # TODO(marcink): set whitespace/context + context_lcl = 3 + ign_whitespace_lcl = False + + for commit in c.commit_ranges: + commit2 = commit + commit1 = commit.first_parent + + range_diff_cache_file_path = diff_cache_exist( + cache_path, 'diff', commit.raw_id, + ign_whitespace_lcl, context_lcl, c.fulldiff) + + cached_diff = None + if caching_enabled: + cached_diff = load_cached_diff(range_diff_cache_file_path) + + has_proper_diff_cache = cached_diff and cached_diff.get('diff') + if not force_recache and has_proper_diff_cache: + diffset = cached_diff['diff'] + else: + diffset = self._get_range_diffset( + source_scm, source_repo, + commit1, commit2, diff_limit, file_limit, + c.fulldiff, ign_whitespace_lcl, context_lcl + ) + + # save cached diff + if caching_enabled: + cache_diff(range_diff_cache_file_path, diffset, None) + + c.changes[commit.raw_id] = diffset # this is a hack to properly display links, when creating PR, the # compare view and others uses different notation, and @@ -607,7 +674,7 @@ class RepoPullRequestsView(RepoAppView, commit_cache = collections.OrderedDict() missing_requirements = False try: - pre_load = ["author", "branch", "date", "message"] + pre_load = ["author", "branch", "date", "message", "parents"] show_revs = pull_request_at_ver.revisions for rev in show_revs: comm = commits_source_repo.get_commit( diff --git a/rhodecode/lib/codeblocks.py b/rhodecode/lib/codeblocks.py --- a/rhodecode/lib/codeblocks.py +++ b/rhodecode/lib/codeblocks.py @@ -469,6 +469,13 @@ class DiffSet(object): source_file = self.source_nodes.get(source_filename, source_filename) target_file = self.target_nodes.get(target_filename, target_filename) + raw_id_uid = '' + if self.source_nodes.get(source_filename): + raw_id_uid = self.source_nodes[source_filename].commit.raw_id + + if not raw_id_uid and self.target_nodes.get(target_filename): + # in case this is a new file we only have it in target + raw_id_uid = self.target_nodes[target_filename].commit.raw_id source_filenode, target_filenode = None, None @@ -512,7 +519,9 @@ class DiffSet(object): 'hunks': [], 'hunk_ops': None, 'diffset': self, + 'raw_id': raw_id_uid, }) + file_chunks = patch['chunks'][1:] for hunk in file_chunks: hunkbit = self.parse_hunk(hunk, source_file, target_file) diff --git a/rhodecode/lib/vcs/backends/base.py b/rhodecode/lib/vcs/backends/base.py --- a/rhodecode/lib/vcs/backends/base.py +++ b/rhodecode/lib/vcs/backends/base.py @@ -821,6 +821,13 @@ class BaseCommit(object): """ raise NotImplementedError + @LazyProperty + def first_parent(self): + """ + Returns list of parent commits. + """ + return self.parents[0] if self.parents else EmptyCommit() + @property def merge(self): """ @@ -1099,8 +1106,7 @@ class BaseCommit(object): """ Returns a `Diff` object representing the change made by this commit. """ - parent = ( - self.parents[0] if self.parents else self.repository.EMPTY_COMMIT) + parent = self.first_parent diff = self.repository.get_diff( parent, self, ignore_whitespace=ignore_whitespace, diff --git a/rhodecode/templates/codeblocks/diffs.mako b/rhodecode/templates/codeblocks/diffs.mako --- a/rhodecode/templates/codeblocks/diffs.mako +++ b/rhodecode/templates/codeblocks/diffs.mako @@ -47,7 +47,7 @@ return '%s_%s_%i' % (h.safeid(filename), deleted_files_comments=None, # for cache purpose - inline_comments=None + inline_comments=None, )"> %if use_comments: @@ -118,7 +118,7 @@ collapse_all = len(diffset.files) > coll

## invidual commit % if commit: - ${('r%s:%s' % (commit.idx,h.short_id(commit.raw_id)))} - + ${('r%s:%s' % (commit.idx,h.short_id(commit.raw_id)))} - ${h.age_component(commit.date)} % if diffset.limited_diff: - ${_('The requested commit is too big and content was truncated.')} @@ -158,7 +158,7 @@ collapse_all = len(diffset.files) > coll