##// END OF EJS Templates
caches: updated cache backend to new vcsserver caches implementation.
marcink -
r3848:fdb508f1 default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,57 +1,57 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2019 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import os
22 22 import sys
23 23 import platform
24 24
25 25 VERSION = tuple(open(os.path.join(
26 26 os.path.dirname(__file__), 'VERSION')).read().split('.'))
27 27
28 28 BACKENDS = {
29 29 'hg': 'Mercurial repository',
30 30 'git': 'Git repository',
31 31 'svn': 'Subversion repository',
32 32 }
33 33
34 34 CELERY_ENABLED = False
35 35 CELERY_EAGER = False
36 36
37 37 # link to config for pyramid
38 38 CONFIG = {}
39 39
40 40 # Populated with the settings dictionary from application init in
41 41 # rhodecode.conf.environment.load_pyramid_environment
42 42 PYRAMID_SETTINGS = {}
43 43
44 44 # Linked module for extensions
45 45 EXTENSIONS = {}
46 46
47 47 __version__ = ('.'.join((str(each) for each in VERSION[:3])))
48 __dbversion__ = 98 # defines current db version for migrations
48 __dbversion__ = 99 # defines current db version for migrations
49 49 __platform__ = platform.system()
50 50 __license__ = 'AGPLv3, and Commercial License'
51 51 __author__ = 'RhodeCode GmbH'
52 52 __url__ = 'https://code.rhodecode.com'
53 53
54 54 is_windows = __platform__ in ['Windows']
55 55 is_unix = not is_windows
56 56 is_test = False
57 57 disable_error_handler = False
@@ -1,501 +1,500 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2019 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21
22 22 import logging
23 23 import collections
24 24
25 25 from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest, HTTPFound
26 26 from pyramid.view import view_config
27 27 from pyramid.renderers import render
28 28 from pyramid.response import Response
29 29
30 30 from rhodecode.apps._base import RepoAppView
31 31
32 32 from rhodecode.lib import diffs, codeblocks
33 33 from rhodecode.lib.auth import (
34 34 LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, CSRFRequired)
35 35
36 36 from rhodecode.lib.compat import OrderedDict
37 37 from rhodecode.lib.diffs import (
38 38 cache_diff, load_cached_diff, diff_cache_exist, get_diff_context,
39 39 get_diff_whitespace_flag)
40 40 from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError
41 41 import rhodecode.lib.helpers as h
42 42 from rhodecode.lib.utils2 import safe_unicode, str2bool
43 43 from rhodecode.lib.vcs.backends.base import EmptyCommit
44 44 from rhodecode.lib.vcs.exceptions import (
45 45 RepositoryError, CommitDoesNotExistError)
46 46 from rhodecode.model.db import ChangesetComment, ChangesetStatus
47 47 from rhodecode.model.changeset_status import ChangesetStatusModel
48 48 from rhodecode.model.comment import CommentsModel
49 49 from rhodecode.model.meta import Session
50 50 from rhodecode.model.settings import VcsSettingsModel
51 51
52 52 log = logging.getLogger(__name__)
53 53
54 54
55 55 def _update_with_GET(params, request):
56 56 for k in ['diff1', 'diff2', 'diff']:
57 57 params[k] += request.GET.getall(k)
58 58
59 59
60
61
62
63 60 class RepoCommitsView(RepoAppView):
64 61 def load_default_context(self):
65 62 c = self._get_local_tmpl_context(include_app_defaults=True)
66 63 c.rhodecode_repo = self.rhodecode_vcs_repo
67 64
68 65 return c
69 66
70 67 def _is_diff_cache_enabled(self, target_repo):
71 68 caching_enabled = self._get_general_setting(
72 69 target_repo, 'rhodecode_diff_cache')
73 70 log.debug('Diff caching enabled: %s', caching_enabled)
74 71 return caching_enabled
75 72
76 73 def _commit(self, commit_id_range, method):
77 74 _ = self.request.translate
78 75 c = self.load_default_context()
79 76 c.fulldiff = self.request.GET.get('fulldiff')
80 77
81 78 # fetch global flags of ignore ws or context lines
82 79 diff_context = get_diff_context(self.request)
83 80 hide_whitespace_changes = get_diff_whitespace_flag(self.request)
84 81
85 82 # diff_limit will cut off the whole diff if the limit is applied
86 83 # otherwise it will just hide the big files from the front-end
87 84 diff_limit = c.visual.cut_off_limit_diff
88 85 file_limit = c.visual.cut_off_limit_file
89 86
90 87 # get ranges of commit ids if preset
91 88 commit_range = commit_id_range.split('...')[:2]
92 89
93 90 try:
94 91 pre_load = ['affected_files', 'author', 'branch', 'date',
95 92 'message', 'parents']
93 if self.rhodecode_vcs_repo.alias == 'hg':
94 pre_load += ['hidden', 'obsolete', 'phase']
96 95
97 96 if len(commit_range) == 2:
98 97 commits = self.rhodecode_vcs_repo.get_commits(
99 98 start_id=commit_range[0], end_id=commit_range[1],
100 99 pre_load=pre_load, translate_tags=False)
101 100 commits = list(commits)
102 101 else:
103 102 commits = [self.rhodecode_vcs_repo.get_commit(
104 103 commit_id=commit_id_range, pre_load=pre_load)]
105 104
106 105 c.commit_ranges = commits
107 106 if not c.commit_ranges:
108 107 raise RepositoryError('The commit range returned an empty result')
109 108 except CommitDoesNotExistError as e:
110 109 msg = _('No such commit exists. Org exception: `{}`').format(e)
111 110 h.flash(msg, category='error')
112 111 raise HTTPNotFound()
113 112 except Exception:
114 113 log.exception("General failure")
115 114 raise HTTPNotFound()
116 115
117 116 c.changes = OrderedDict()
118 117 c.lines_added = 0
119 118 c.lines_deleted = 0
120 119
121 120 # auto collapse if we have more than limit
122 121 collapse_limit = diffs.DiffProcessor._collapse_commits_over
123 122 c.collapse_all_commits = len(c.commit_ranges) > collapse_limit
124 123
125 124 c.commit_statuses = ChangesetStatus.STATUSES
126 125 c.inline_comments = []
127 126 c.files = []
128 127
129 128 c.statuses = []
130 129 c.comments = []
131 130 c.unresolved_comments = []
132 131 if len(c.commit_ranges) == 1:
133 132 commit = c.commit_ranges[0]
134 133 c.comments = CommentsModel().get_comments(
135 134 self.db_repo.repo_id,
136 135 revision=commit.raw_id)
137 136 c.statuses.append(ChangesetStatusModel().get_status(
138 137 self.db_repo.repo_id, commit.raw_id))
139 138 # comments from PR
140 139 statuses = ChangesetStatusModel().get_statuses(
141 140 self.db_repo.repo_id, commit.raw_id,
142 141 with_revisions=True)
143 142 prs = set(st.pull_request for st in statuses
144 143 if st.pull_request is not None)
145 144 # from associated statuses, check the pull requests, and
146 145 # show comments from them
147 146 for pr in prs:
148 147 c.comments.extend(pr.comments)
149 148
150 149 c.unresolved_comments = CommentsModel()\
151 150 .get_commit_unresolved_todos(commit.raw_id)
152 151
153 152 diff = None
154 153 # Iterate over ranges (default commit view is always one commit)
155 154 for commit in c.commit_ranges:
156 155 c.changes[commit.raw_id] = []
157 156
158 157 commit2 = commit
159 158 commit1 = commit.first_parent
160 159
161 160 if method == 'show':
162 161 inline_comments = CommentsModel().get_inline_comments(
163 162 self.db_repo.repo_id, revision=commit.raw_id)
164 163 c.inline_cnt = CommentsModel().get_inline_comments_count(
165 164 inline_comments)
166 165 c.inline_comments = inline_comments
167 166
168 167 cache_path = self.rhodecode_vcs_repo.get_create_shadow_cache_pr_path(
169 168 self.db_repo)
170 169 cache_file_path = diff_cache_exist(
171 170 cache_path, 'diff', commit.raw_id,
172 171 hide_whitespace_changes, diff_context, c.fulldiff)
173 172
174 173 caching_enabled = self._is_diff_cache_enabled(self.db_repo)
175 174 force_recache = str2bool(self.request.GET.get('force_recache'))
176 175
177 176 cached_diff = None
178 177 if caching_enabled:
179 178 cached_diff = load_cached_diff(cache_file_path)
180 179
181 180 has_proper_diff_cache = cached_diff and cached_diff.get('diff')
182 181 if not force_recache and has_proper_diff_cache:
183 182 diffset = cached_diff['diff']
184 183 else:
185 184 vcs_diff = self.rhodecode_vcs_repo.get_diff(
186 185 commit1, commit2,
187 186 ignore_whitespace=hide_whitespace_changes,
188 187 context=diff_context)
189 188
190 189 diff_processor = diffs.DiffProcessor(
191 190 vcs_diff, format='newdiff', diff_limit=diff_limit,
192 191 file_limit=file_limit, show_full_diff=c.fulldiff)
193 192
194 193 _parsed = diff_processor.prepare()
195 194
196 195 diffset = codeblocks.DiffSet(
197 196 repo_name=self.db_repo_name,
198 197 source_node_getter=codeblocks.diffset_node_getter(commit1),
199 198 target_node_getter=codeblocks.diffset_node_getter(commit2))
200 199
201 200 diffset = self.path_filter.render_patchset_filtered(
202 201 diffset, _parsed, commit1.raw_id, commit2.raw_id)
203 202
204 203 # save cached diff
205 204 if caching_enabled:
206 205 cache_diff(cache_file_path, diffset, None)
207 206
208 207 c.limited_diff = diffset.limited_diff
209 208 c.changes[commit.raw_id] = diffset
210 209 else:
211 210 # TODO(marcink): no cache usage here...
212 211 _diff = self.rhodecode_vcs_repo.get_diff(
213 212 commit1, commit2,
214 213 ignore_whitespace=hide_whitespace_changes, context=diff_context)
215 214 diff_processor = diffs.DiffProcessor(
216 215 _diff, format='newdiff', diff_limit=diff_limit,
217 216 file_limit=file_limit, show_full_diff=c.fulldiff)
218 217 # downloads/raw we only need RAW diff nothing else
219 218 diff = self.path_filter.get_raw_patch(diff_processor)
220 219 c.changes[commit.raw_id] = [None, None, None, None, diff, None, None]
221 220
222 221 # sort comments by how they were generated
223 222 c.comments = sorted(c.comments, key=lambda x: x.comment_id)
224 223
225 224 if len(c.commit_ranges) == 1:
226 225 c.commit = c.commit_ranges[0]
227 226 c.parent_tmpl = ''.join(
228 227 '# Parent %s\n' % x.raw_id for x in c.commit.parents)
229 228
230 229 if method == 'download':
231 230 response = Response(diff)
232 231 response.content_type = 'text/plain'
233 232 response.content_disposition = (
234 233 'attachment; filename=%s.diff' % commit_id_range[:12])
235 234 return response
236 235 elif method == 'patch':
237 236 c.diff = safe_unicode(diff)
238 237 patch = render(
239 238 'rhodecode:templates/changeset/patch_changeset.mako',
240 239 self._get_template_context(c), self.request)
241 240 response = Response(patch)
242 241 response.content_type = 'text/plain'
243 242 return response
244 243 elif method == 'raw':
245 244 response = Response(diff)
246 245 response.content_type = 'text/plain'
247 246 return response
248 247 elif method == 'show':
249 248 if len(c.commit_ranges) == 1:
250 249 html = render(
251 250 'rhodecode:templates/changeset/changeset.mako',
252 251 self._get_template_context(c), self.request)
253 252 return Response(html)
254 253 else:
255 254 c.ancestor = None
256 255 c.target_repo = self.db_repo
257 256 html = render(
258 257 'rhodecode:templates/changeset/changeset_range.mako',
259 258 self._get_template_context(c), self.request)
260 259 return Response(html)
261 260
262 261 raise HTTPBadRequest()
263 262
264 263 @LoginRequired()
265 264 @HasRepoPermissionAnyDecorator(
266 265 'repository.read', 'repository.write', 'repository.admin')
267 266 @view_config(
268 267 route_name='repo_commit', request_method='GET',
269 268 renderer=None)
270 269 def repo_commit_show(self):
271 270 commit_id = self.request.matchdict['commit_id']
272 271 return self._commit(commit_id, method='show')
273 272
274 273 @LoginRequired()
275 274 @HasRepoPermissionAnyDecorator(
276 275 'repository.read', 'repository.write', 'repository.admin')
277 276 @view_config(
278 277 route_name='repo_commit_raw', request_method='GET',
279 278 renderer=None)
280 279 @view_config(
281 280 route_name='repo_commit_raw_deprecated', request_method='GET',
282 281 renderer=None)
283 282 def repo_commit_raw(self):
284 283 commit_id = self.request.matchdict['commit_id']
285 284 return self._commit(commit_id, method='raw')
286 285
287 286 @LoginRequired()
288 287 @HasRepoPermissionAnyDecorator(
289 288 'repository.read', 'repository.write', 'repository.admin')
290 289 @view_config(
291 290 route_name='repo_commit_patch', request_method='GET',
292 291 renderer=None)
293 292 def repo_commit_patch(self):
294 293 commit_id = self.request.matchdict['commit_id']
295 294 return self._commit(commit_id, method='patch')
296 295
297 296 @LoginRequired()
298 297 @HasRepoPermissionAnyDecorator(
299 298 'repository.read', 'repository.write', 'repository.admin')
300 299 @view_config(
301 300 route_name='repo_commit_download', request_method='GET',
302 301 renderer=None)
303 302 def repo_commit_download(self):
304 303 commit_id = self.request.matchdict['commit_id']
305 304 return self._commit(commit_id, method='download')
306 305
307 306 @LoginRequired()
308 307 @NotAnonymous()
309 308 @HasRepoPermissionAnyDecorator(
310 309 'repository.read', 'repository.write', 'repository.admin')
311 310 @CSRFRequired()
312 311 @view_config(
313 312 route_name='repo_commit_comment_create', request_method='POST',
314 313 renderer='json_ext')
315 314 def repo_commit_comment_create(self):
316 315 _ = self.request.translate
317 316 commit_id = self.request.matchdict['commit_id']
318 317
319 318 c = self.load_default_context()
320 319 status = self.request.POST.get('changeset_status', None)
321 320 text = self.request.POST.get('text')
322 321 comment_type = self.request.POST.get('comment_type')
323 322 resolves_comment_id = self.request.POST.get('resolves_comment_id', None)
324 323
325 324 if status:
326 325 text = text or (_('Status change %(transition_icon)s %(status)s')
327 326 % {'transition_icon': '>',
328 327 'status': ChangesetStatus.get_status_lbl(status)})
329 328
330 329 multi_commit_ids = []
331 330 for _commit_id in self.request.POST.get('commit_ids', '').split(','):
332 331 if _commit_id not in ['', None, EmptyCommit.raw_id]:
333 332 if _commit_id not in multi_commit_ids:
334 333 multi_commit_ids.append(_commit_id)
335 334
336 335 commit_ids = multi_commit_ids or [commit_id]
337 336
338 337 comment = None
339 338 for current_id in filter(None, commit_ids):
340 339 comment = CommentsModel().create(
341 340 text=text,
342 341 repo=self.db_repo.repo_id,
343 342 user=self._rhodecode_db_user.user_id,
344 343 commit_id=current_id,
345 344 f_path=self.request.POST.get('f_path'),
346 345 line_no=self.request.POST.get('line'),
347 346 status_change=(ChangesetStatus.get_status_lbl(status)
348 347 if status else None),
349 348 status_change_type=status,
350 349 comment_type=comment_type,
351 350 resolves_comment_id=resolves_comment_id,
352 351 auth_user=self._rhodecode_user
353 352 )
354 353
355 354 # get status if set !
356 355 if status:
357 356 # if latest status was from pull request and it's closed
358 357 # disallow changing status !
359 358 # dont_allow_on_closed_pull_request = True !
360 359
361 360 try:
362 361 ChangesetStatusModel().set_status(
363 362 self.db_repo.repo_id,
364 363 status,
365 364 self._rhodecode_db_user.user_id,
366 365 comment,
367 366 revision=current_id,
368 367 dont_allow_on_closed_pull_request=True
369 368 )
370 369 except StatusChangeOnClosedPullRequestError:
371 370 msg = _('Changing the status of a commit associated with '
372 371 'a closed pull request is not allowed')
373 372 log.exception(msg)
374 373 h.flash(msg, category='warning')
375 374 raise HTTPFound(h.route_path(
376 375 'repo_commit', repo_name=self.db_repo_name,
377 376 commit_id=current_id))
378 377
379 378 # finalize, commit and redirect
380 379 Session().commit()
381 380
382 381 data = {
383 382 'target_id': h.safeid(h.safe_unicode(
384 383 self.request.POST.get('f_path'))),
385 384 }
386 385 if comment:
387 386 c.co = comment
388 387 rendered_comment = render(
389 388 'rhodecode:templates/changeset/changeset_comment_block.mako',
390 389 self._get_template_context(c), self.request)
391 390
392 391 data.update(comment.get_dict())
393 392 data.update({'rendered_text': rendered_comment})
394 393
395 394 return data
396 395
397 396 @LoginRequired()
398 397 @NotAnonymous()
399 398 @HasRepoPermissionAnyDecorator(
400 399 'repository.read', 'repository.write', 'repository.admin')
401 400 @CSRFRequired()
402 401 @view_config(
403 402 route_name='repo_commit_comment_preview', request_method='POST',
404 403 renderer='string', xhr=True)
405 404 def repo_commit_comment_preview(self):
406 405 # Technically a CSRF token is not needed as no state changes with this
407 406 # call. However, as this is a POST is better to have it, so automated
408 407 # tools don't flag it as potential CSRF.
409 408 # Post is required because the payload could be bigger than the maximum
410 409 # allowed by GET.
411 410
412 411 text = self.request.POST.get('text')
413 412 renderer = self.request.POST.get('renderer') or 'rst'
414 413 if text:
415 414 return h.render(text, renderer=renderer, mentions=True)
416 415 return ''
417 416
418 417 @LoginRequired()
419 418 @NotAnonymous()
420 419 @HasRepoPermissionAnyDecorator(
421 420 'repository.read', 'repository.write', 'repository.admin')
422 421 @CSRFRequired()
423 422 @view_config(
424 423 route_name='repo_commit_comment_delete', request_method='POST',
425 424 renderer='json_ext')
426 425 def repo_commit_comment_delete(self):
427 426 commit_id = self.request.matchdict['commit_id']
428 427 comment_id = self.request.matchdict['comment_id']
429 428
430 429 comment = ChangesetComment.get_or_404(comment_id)
431 430 if not comment:
432 431 log.debug('Comment with id:%s not found, skipping', comment_id)
433 432 # comment already deleted in another call probably
434 433 return True
435 434
436 435 is_repo_admin = h.HasRepoPermissionAny('repository.admin')(self.db_repo_name)
437 436 super_admin = h.HasPermissionAny('hg.admin')()
438 437 comment_owner = (comment.author.user_id == self._rhodecode_db_user.user_id)
439 438 is_repo_comment = comment.repo.repo_name == self.db_repo_name
440 439 comment_repo_admin = is_repo_admin and is_repo_comment
441 440
442 441 if super_admin or comment_owner or comment_repo_admin:
443 442 CommentsModel().delete(comment=comment, auth_user=self._rhodecode_user)
444 443 Session().commit()
445 444 return True
446 445 else:
447 446 log.warning('No permissions for user %s to delete comment_id: %s',
448 447 self._rhodecode_db_user, comment_id)
449 448 raise HTTPNotFound()
450 449
451 450 @LoginRequired()
452 451 @HasRepoPermissionAnyDecorator(
453 452 'repository.read', 'repository.write', 'repository.admin')
454 453 @view_config(
455 454 route_name='repo_commit_data', request_method='GET',
456 455 renderer='json_ext', xhr=True)
457 456 def repo_commit_data(self):
458 457 commit_id = self.request.matchdict['commit_id']
459 458 self.load_default_context()
460 459
461 460 try:
462 461 return self.rhodecode_vcs_repo.get_commit(commit_id=commit_id)
463 462 except CommitDoesNotExistError as e:
464 463 return EmptyCommit(message=str(e))
465 464
466 465 @LoginRequired()
467 466 @HasRepoPermissionAnyDecorator(
468 467 'repository.read', 'repository.write', 'repository.admin')
469 468 @view_config(
470 469 route_name='repo_commit_children', request_method='GET',
471 470 renderer='json_ext', xhr=True)
472 471 def repo_commit_children(self):
473 472 commit_id = self.request.matchdict['commit_id']
474 473 self.load_default_context()
475 474
476 475 try:
477 476 commit = self.rhodecode_vcs_repo.get_commit(commit_id=commit_id)
478 477 children = commit.children
479 478 except CommitDoesNotExistError:
480 479 children = []
481 480
482 481 result = {"results": children}
483 482 return result
484 483
485 484 @LoginRequired()
486 485 @HasRepoPermissionAnyDecorator(
487 486 'repository.read', 'repository.write', 'repository.admin')
488 487 @view_config(
489 488 route_name='repo_commit_parents', request_method='GET',
490 489 renderer='json_ext')
491 490 def repo_commit_parents(self):
492 491 commit_id = self.request.matchdict['commit_id']
493 492 self.load_default_context()
494 493
495 494 try:
496 495 commit = self.rhodecode_vcs_repo.get_commit(commit_id=commit_id)
497 496 parents = commit.parents
498 497 except CommitDoesNotExistError:
499 498 parents = []
500 499 result = {"results": parents}
501 500 return result
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now