##// END OF EJS Templates
move the existing changeset checks bellow other checks else it can throw exceptions for non...
marcink -
r3615:50927aed beta
parent child Browse files
Show More
@@ -1,188 +1,188 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.compare
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 compare controller for pylons showing differences between two
7 7 repos, branches, bookmarks or tips
8 8
9 9 :created_on: May 6, 2012
10 10 :author: marcink
11 11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
12 12 :license: GPLv3, see COPYING for more details.
13 13 """
14 14 # This program is free software: you can redistribute it and/or modify
15 15 # it under the terms of the GNU General Public License as published by
16 16 # the Free Software Foundation, either version 3 of the License, or
17 17 # (at your option) any later version.
18 18 #
19 19 # This program is distributed in the hope that it will be useful,
20 20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 22 # GNU General Public License for more details.
23 23 #
24 24 # You should have received a copy of the GNU General Public License
25 25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 26 import logging
27 27 import traceback
28 28
29 29 from webob.exc import HTTPNotFound
30 30 from pylons import request, response, session, tmpl_context as c, url
31 31 from pylons.controllers.util import abort, redirect
32 32 from pylons.i18n.translation import _
33 33
34 34 from rhodecode.lib.vcs.exceptions import EmptyRepositoryError, RepositoryError
35 35 from rhodecode.lib import helpers as h
36 36 from rhodecode.lib.base import BaseRepoController, render
37 37 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
38 38 from rhodecode.lib import diffs
39 39
40 40 from rhodecode.model.db import Repository
41 41 from rhodecode.model.pull_request import PullRequestModel
42 42 from webob.exc import HTTPBadRequest
43 43 from rhodecode.lib.diffs import LimitedDiffContainer
44 44 from rhodecode.lib.vcs.backends.base import EmptyChangeset
45 45
46 46 log = logging.getLogger(__name__)
47 47
48 48
49 49 class CompareController(BaseRepoController):
50 50
51 51 @LoginRequired()
52 52 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
53 53 'repository.admin')
54 54 def __before__(self):
55 55 super(CompareController, self).__before__()
56 56
57 57 def __get_cs_or_redirect(self, rev, repo, redirect_after=True,
58 58 partial=False):
59 59 """
60 60 Safe way to get changeset if error occur it redirects to changeset with
61 61 proper message. If partial is set then don't do redirect raise Exception
62 62 instead
63 63
64 64 :param rev: revision to fetch
65 65 :param repo: repo instance
66 66 """
67 67
68 68 try:
69 69 type_, rev = rev
70 70 return repo.scm_instance.get_changeset(rev)
71 71 except EmptyRepositoryError, e:
72 72 if not redirect_after:
73 73 return None
74 74 h.flash(h.literal(_('There are no changesets yet')),
75 75 category='warning')
76 76 redirect(url('summary_home', repo_name=repo.repo_name))
77 77
78 78 except RepositoryError, e:
79 79 log.error(traceback.format_exc())
80 80 h.flash(str(e), category='warning')
81 81 if not partial:
82 82 redirect(h.url('summary_home', repo_name=repo.repo_name))
83 83 raise HTTPBadRequest()
84 84
85 85 def index(self, org_ref_type, org_ref, other_ref_type, other_ref):
86 86 # org_ref will be evaluated in org_repo
87 87 org_repo = c.rhodecode_db_repo.repo_name
88 88 org_ref = (org_ref_type, org_ref)
89 89 # other_ref will be evaluated in other_repo
90 90 other_ref = (other_ref_type, other_ref)
91 91 other_repo = request.GET.get('other_repo', org_repo)
92 92 # If merge is True:
93 93 # Show what org would get if merged with other:
94 94 # List changesets that are ancestors of other but not of org.
95 95 # New changesets in org is thus ignored.
96 96 # Diff will be from common ancestor, and merges of org to other will thus be ignored.
97 97 # If merge is False:
98 98 # Make a raw diff from org to other, no matter if related or not.
99 99 # Changesets in one and not in the other will be ignored
100 100 merge = bool(request.GET.get('merge'))
101 101 # fulldiff disables cut_off_limit
102 102 c.fulldiff = request.GET.get('fulldiff')
103 103 # partial uses compare_cs.html template directly
104 104 partial = request.environ.get('HTTP_X_PARTIAL_XHR')
105 105 # as_form puts hidden input field with changeset revisions
106 106 c.as_form = partial and request.GET.get('as_form')
107 107 # swap url for compare_diff page - never partial and never as_form
108 108 c.swap_url = h.url('compare_url',
109 109 repo_name=other_repo,
110 110 org_ref_type=other_ref[0], org_ref=other_ref[1],
111 111 other_repo=org_repo,
112 112 other_ref_type=org_ref[0], other_ref=org_ref[1],
113 113 merge=merge or '')
114 114
115 115 org_repo = Repository.get_by_repo_name(org_repo)
116 116 other_repo = Repository.get_by_repo_name(other_repo)
117 117
118 self.__get_cs_or_redirect(rev=org_ref, repo=org_repo, partial=partial)
119 self.__get_cs_or_redirect(rev=other_ref, repo=other_repo, partial=partial)
120
121 118 if org_repo is None:
122 119 log.error('Could not find org repo %s' % org_repo)
123 120 raise HTTPNotFound
124 121 if other_repo is None:
125 122 log.error('Could not find other repo %s' % other_repo)
126 123 raise HTTPNotFound
127 124
128 125 if org_repo != other_repo and h.is_git(org_repo):
129 126 log.error('compare of two remote repos not available for GIT REPOS')
130 127 raise HTTPNotFound
131 128
132 129 if org_repo.scm_instance.alias != other_repo.scm_instance.alias:
133 130 log.error('compare of two different kind of remote repos not available')
134 131 raise HTTPNotFound
135 132
133 self.__get_cs_or_redirect(rev=org_ref, repo=org_repo, partial=partial)
134 self.__get_cs_or_redirect(rev=other_ref, repo=other_repo, partial=partial)
135
136 136 c.org_repo = org_repo
137 137 c.other_repo = other_repo
138 138 c.org_ref = org_ref[1]
139 139 c.other_ref = other_ref[1]
140 140 c.org_ref_type = org_ref[0]
141 141 c.other_ref_type = other_ref[0]
142 142
143 143 c.cs_ranges, c.ancestor = PullRequestModel().get_compare_data(
144 144 org_repo, org_ref, other_repo, other_ref, merge)
145 145
146 146 c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in
147 147 c.cs_ranges])
148 148 if partial:
149 149 assert c.ancestor
150 150 return render('compare/compare_cs.html')
151 151
152 152 if c.ancestor:
153 153 assert merge
154 154 # case we want a simple diff without incoming changesets,
155 155 # previewing what will be merged.
156 156 # Make the diff on the other repo (which is known to have other_ref)
157 157 log.debug('Using ancestor %s as org_ref instead of %s'
158 158 % (c.ancestor, org_ref))
159 159 org_ref = ('rev', c.ancestor)
160 160 org_repo = other_repo
161 161
162 162 diff_limit = self.cut_off_limit if not c.fulldiff else None
163 163
164 164 _diff = diffs.differ(org_repo, org_ref, other_repo, other_ref)
165 165
166 166 diff_processor = diffs.DiffProcessor(_diff or '', format='gitdiff',
167 167 diff_limit=diff_limit)
168 168 _parsed = diff_processor.prepare()
169 169
170 170 c.limited_diff = False
171 171 if isinstance(_parsed, LimitedDiffContainer):
172 172 c.limited_diff = True
173 173
174 174 c.files = []
175 175 c.changes = {}
176 176 c.lines_added = 0
177 177 c.lines_deleted = 0
178 178 for f in _parsed:
179 179 st = f['stats']
180 180 if st[0] != 'b':
181 181 c.lines_added += st[0]
182 182 c.lines_deleted += st[1]
183 183 fid = h.FID('', f['filename'])
184 184 c.files.append([fid, f['operation'], f['filename'], f['stats']])
185 185 diff = diff_processor.as_html(enable_comments=False, parsed_lines=[f])
186 186 c.changes[fid] = [f['operation'], f['filename'], diff]
187 187
188 188 return render('compare/compare_diff.html')
General Comments 0
You need to be logged in to leave comments. Login now