##// END OF EJS Templates
user-groups: fix potential problem with group sync of external plugins....
user-groups: fix potential problem with group sync of external plugins. - when using external plugin we used to check for a parameter that set the sync mode. The problem is we only checked if the flag was there. So toggling sync on and off set the value and then left the key still set but with None. This confused the sync and thought the group should be synced !

File last commit:

r1844:ecd2b149 default
r2193:20e24a44 stable
Show More
compare.py
286 lines | 11.5 KiB | text/x-python | PythonLexer
project: added all source files and assets
r1 # -*- coding: utf-8 -*-
license: updated copyright year to 2017
r1271 # Copyright (C) 2012-2017 RhodeCode GmbH
project: added all source files and assets
r1 #
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License, version 3
# (only), as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This program is dual-licensed. If you wish to learn more about the
# RhodeCode Enterprise Edition, including its added features, Support services,
# and proprietary license terms, please see https://rhodecode.com/licenses/
"""
Compare controller for showing differences between two commits/refs/tags etc.
"""
import logging
security: escape flash messaged VCS errors to prevent XSS atacks.
r1838 from webob.exc import HTTPBadRequest, HTTPNotFound
project: added all source files and assets
r1 from pylons import request, tmpl_context as c, url
from pylons.controllers.util import redirect
from pylons.i18n.translation import _
from rhodecode.controllers.utils import parse_path_ref, get_commit_from_ref_name
from rhodecode.lib import helpers as h
dan
diffs: replace compare controller with new html based diffs:...
r1030 from rhodecode.lib import diffs, codeblocks
project: added all source files and assets
r1 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
from rhodecode.lib.base import BaseRepoController, render
from rhodecode.lib.utils import safe_str
from rhodecode.lib.utils2 import safe_unicode, str2bool
from rhodecode.lib.vcs.exceptions import (
dan
diffs: replace compare controller with new html based diffs:...
r1030 EmptyRepositoryError, RepositoryError, RepositoryRequirementError,
NodeDoesNotExistError)
project: added all source files and assets
r1 from rhodecode.model.db import Repository, ChangesetStatus
log = logging.getLogger(__name__)
class CompareController(BaseRepoController):
def __before__(self):
super(CompareController, self).__before__()
def _get_commit_or_redirect(
self, ref, ref_type, repo, redirect_after=True, partial=False):
"""
This is a safe way to get a commit. If an error occurs it
redirects to a commit with a proper message. If partial is set
then it does not do redirect raise and throws an exception instead.
"""
try:
return get_commit_from_ref_name(repo, safe_str(ref), ref_type)
except EmptyRepositoryError:
if not redirect_after:
return repo.scm_instance().EMPTY_COMMIT
h.flash(h.literal(_('There are no commits yet')),
category='warning')
repo-summary: re-implemented summary view as pyramid....
r1785 redirect(h.route_path('repo_summary', repo_name=repo.repo_name))
project: added all source files and assets
r1
except RepositoryError as e:
security: escape flash messaged VCS errors to prevent XSS atacks.
r1838 log.exception(safe_str(e))
h.flash(safe_str(h.escape(e)), category='warning')
project: added all source files and assets
r1 if not partial:
repo-summary: re-implemented summary view as pyramid....
r1785 redirect(h.route_path('repo_summary', repo_name=repo.repo_name))
project: added all source files and assets
r1 raise HTTPBadRequest()
@LoginRequired()
@HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
'repository.admin')
def index(self, repo_name):
c.compare_home = True
c.commit_ranges = []
pull-requests: updated versioning support....
r1268 c.collapse_all_commits = False
dan
diffs: replace compare controller with new html based diffs:...
r1030 c.diffset = None
project: added all source files and assets
r1 c.limited_diff = False
source_repo = c.rhodecode_db_repo.repo_name
target_repo = request.GET.get('target_repo', source_repo)
c.source_repo = Repository.get_by_repo_name(source_repo)
c.target_repo = Repository.get_by_repo_name(target_repo)
security: escape flash messaged VCS errors to prevent XSS atacks.
r1838
if c.source_repo is None or c.target_repo is None:
raise HTTPNotFound()
project: added all source files and assets
r1 c.source_ref = c.target_ref = _('Select commit')
c.source_ref_type = ""
c.target_ref_type = ""
c.commit_statuses = ChangesetStatus.STATUSES
c.preview_mode = False
diffs: compare overhaul....
r1259 c.file_path = None
templating: use .mako as extensions for template files.
r1282 return render('compare/compare_diff.mako')
project: added all source files and assets
r1
@LoginRequired()
@HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
'repository.admin')
def compare(self, repo_name, source_ref_type, source_ref,
target_ref_type, target_ref):
# source_ref will be evaluated in source_repo
source_repo_name = c.rhodecode_db_repo.repo_name
source_path, source_id = parse_path_ref(source_ref)
# target_ref will be evaluated in target_repo
target_repo_name = request.GET.get('target_repo', source_repo_name)
diffs: compare overhaul....
r1259 target_path, target_id = parse_path_ref(
target_ref, default_path=request.GET.get('f_path', ''))
project: added all source files and assets
r1
diffs: compare overhaul....
r1259 c.file_path = target_path
project: added all source files and assets
r1 c.commit_statuses = ChangesetStatus.STATUSES
# if merge is True
# Show what changes since the shared ancestor commit of target/source
# the source would get if it was merged with target. Only commits
# which are in target but not in source will be shown.
merge = str2bool(request.GET.get('merge'))
# if merge is False
# Show a raw diff of source/target refs even if no ancestor exists
# c.fulldiff disables cut_off_limit
c.fulldiff = str2bool(request.GET.get('fulldiff'))
# if partial, returns just compare_commits.html (commits log)
partial = request.is_xhr
# swap url for compare_diff page
c.swap_url = h.url(
'compare_url',
repo_name=target_repo_name,
source_ref_type=target_ref_type,
source_ref=target_ref,
target_repo=source_repo_name,
target_ref_type=source_ref_type,
target_ref=source_ref,
diffs: compare overhaul....
r1259 merge=merge and '1' or '',
f_path=target_path)
project: added all source files and assets
r1
source_repo = Repository.get_by_repo_name(source_repo_name)
target_repo = Repository.get_by_repo_name(target_repo_name)
if source_repo is None:
security: escape flash messaged VCS errors to prevent XSS atacks.
r1838 log.error('Could not find the source repo: {}'
.format(source_repo_name))
h.flash(_('Could not find the source repo: `{}`')
.format(h.escape(source_repo_name)), category='error')
project: added all source files and assets
r1 return redirect(url('compare_home', repo_name=c.repo_name))
if target_repo is None:
security: escape flash messaged VCS errors to prevent XSS atacks.
r1838 log.error('Could not find the target repo: {}'
.format(source_repo_name))
h.flash(_('Could not find the target repo: `{}`')
.format(h.escape(target_repo_name)), category='error')
project: added all source files and assets
r1 return redirect(url('compare_home', repo_name=c.repo_name))
diffs: compare overhaul....
r1259 source_scm = source_repo.scm_instance()
target_scm = target_repo.scm_instance()
source_alias = source_scm.alias
target_alias = target_scm.alias
project: added all source files and assets
r1 if source_alias != target_alias:
msg = _('The comparison of two different kinds of remote repos '
'is not available')
log.error(msg)
h.flash(msg, category='error')
return redirect(url('compare_home', repo_name=c.repo_name))
source_commit = self._get_commit_or_redirect(
ref=source_id, ref_type=source_ref_type, repo=source_repo,
partial=partial)
target_commit = self._get_commit_or_redirect(
ref=target_id, ref_type=target_ref_type, repo=target_repo,
partial=partial)
c.compare_home = False
c.source_repo = source_repo
c.target_repo = target_repo
c.source_ref = source_ref
c.target_ref = target_ref
c.source_ref_type = source_ref_type
c.target_ref_type = target_ref_type
pre_load = ["author", "branch", "date", "message"]
c.ancestor = None
compare: using f_path shouldn't generate full range of commits....
r1262
if c.file_path:
if source_commit == target_commit:
c.commit_ranges = []
else:
c.commit_ranges = [target_commit]
else:
try:
c.commit_ranges = source_scm.compare(
source_commit.raw_id, target_commit.raw_id,
target_scm, merge, pre_load=pre_load)
if merge:
c.ancestor = source_scm.get_common_ancestor(
source_commit.raw_id, target_commit.raw_id, target_scm)
except RepositoryRequirementError:
msg = _('Could not compare repos with different '
'large file settings')
log.error(msg)
if partial:
return msg
h.flash(msg, category='error')
return redirect(url('compare_home', repo_name=c.repo_name))
project: added all source files and assets
r1
c.statuses = c.rhodecode_db_repo.statuses(
[x.raw_id for x in c.commit_ranges])
pull-requests: updated versioning support....
r1268 # auto collapse if we have more than limit
collapse_limit = diffs.DiffProcessor._collapse_commits_over
c.collapse_all_commits = len(c.commit_ranges) > collapse_limit
diffs: compare overhaul....
r1259 if partial: # for PR ajax commits loader
dan
pullrequest: disable pr on commits that dont share ancestor
r64 if not c.ancestor:
diffs: compare overhaul....
r1259 return '' # cannot merge if there is no ancestor
templating: use .mako as extensions for template files.
r1282 return render('compare/compare_commits.mako')
project: added all source files and assets
r1
if c.ancestor:
# case we want a simple diff without incoming commits,
# previewing what will be merged.
# Make the diff on target repo (which is known to have target_ref)
log.debug('Using ancestor %s as source_ref instead of %s'
% (c.ancestor, source_ref))
source_repo = target_repo
source_commit = target_repo.get_commit(commit_id=c.ancestor)
# diff_limit will cut off the whole diff if the limit is applied
# otherwise it will just hide the big files from the front-end
diff_limit = self.cut_off_limit_diff
file_limit = self.cut_off_limit_file
log.debug('calculating diff between '
'source_ref:%s and target_ref:%s for repo `%s`',
source_commit, target_commit,
safe_unicode(source_repo.scm_instance().path))
if source_commit.repository != target_commit.repository:
msg = _(
"Repositories unrelated. "
"Cannot compare commit %(commit1)s from repository %(repo1)s "
"with commit %(commit2)s from repository %(repo2)s.") % {
'commit1': h.show_id(source_commit),
'repo1': source_repo.repo_name,
'commit2': h.show_id(target_commit),
'repo2': target_repo.repo_name,
}
h.flash(msg, category='error')
raise HTTPBadRequest()
txtdiff = source_repo.scm_instance().get_diff(
commit1=source_commit, commit2=target_commit,
diffs: compare overhaul....
r1259 path=target_path, path1=source_path)
project: added all source files and assets
r1 diff_processor = diffs.DiffProcessor(
dan
diffs: replace compare controller with new html based diffs:...
r1030 txtdiff, format='newdiff', diff_limit=diff_limit,
project: added all source files and assets
r1 file_limit=file_limit, show_full_diff=c.fulldiff)
_parsed = diff_processor.prepare()
dan
diffs: replace compare controller with new html based diffs:...
r1030 def _node_getter(commit):
""" Returns a function that returns a node for a commit or None """
def get_node(fname):
try:
return commit.get_node(fname)
except NodeDoesNotExistError:
return None
return get_node
project: added all source files and assets
r1
diffs: simplified the datastructure of fillediff. Hopefully this...
r1844 diffset = codeblocks.DiffSet(
dan
diffs: add repo_name as parameter of diffset - fixes bug...
r1142 repo_name=source_repo.repo_name,
dan
diffs: replace compare controller with new html based diffs:...
r1030 source_node_getter=_node_getter(source_commit),
target_node_getter=_node_getter(target_commit),
diffs: simplified the datastructure of fillediff. Hopefully this...
r1844 )
c.diffset = diffset.render_patchset(
_parsed, source_ref, target_ref)
project: added all source files and assets
r1
c.preview_mode = merge
diffs: compare overhaul....
r1259 c.source_commit = source_commit
c.target_commit = target_commit
project: added all source files and assets
r1
templating: use .mako as extensions for template files.
r1282 return render('compare/compare_diff.mako')