release: merge back stable branch into default
This commit is contained in:
commit
8781a7b312
26 changed files with 1323 additions and 1111 deletions
42
docs/release-notes/release-notes-4.20.1.rst
Normal file
42
docs/release-notes/release-notes-4.20.1.rst
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
|RCE| 4.20.1 |RNS|
|
||||
------------------
|
||||
|
||||
Release Date
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- 2020-07-27
|
||||
|
||||
|
||||
New Features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
|
||||
|
||||
General
|
||||
^^^^^^^
|
||||
|
||||
- Permissions: rename write+ to write or higher for more explicit meaning.
|
||||
|
||||
|
||||
Security
|
||||
^^^^^^^^
|
||||
|
||||
|
||||
|
||||
Performance
|
||||
^^^^^^^^^^^
|
||||
|
||||
|
||||
|
||||
Fixes
|
||||
^^^^^
|
||||
|
||||
- Files: fixed creation of new files for empty repos.
|
||||
- Notifications: properly inject the custom email headers into templates.
|
||||
- Store file integration: fixed support for nested subdirs.
|
||||
|
||||
|
||||
Upgrade notes
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
- Un-scheduled release addressing problems in 4.20.X releases.
|
||||
|
|
@ -9,6 +9,7 @@ Release Notes
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
release-notes-4.20.1.rst
|
||||
release-notes-4.20.0.rst
|
||||
release-notes-4.19.3.rst
|
||||
release-notes-4.19.2.rst
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ class RepoFilesView(RepoAppView):
|
|||
|
||||
return file_node
|
||||
|
||||
def _is_valid_head(self, commit_id, repo):
|
||||
def _is_valid_head(self, commit_id, repo, landing_ref):
|
||||
branch_name = sha_commit_id = ''
|
||||
is_head = False
|
||||
log.debug('Checking if commit_id `%s` is a head for %s.', commit_id, repo)
|
||||
|
|
@ -237,7 +237,11 @@ class RepoFilesView(RepoAppView):
|
|||
return branch_name, sha_commit_id, is_head
|
||||
|
||||
# checked branches, means we only need to try to get the branch/commit_sha
|
||||
if not repo.is_empty():
|
||||
if repo.is_empty():
|
||||
is_head = True
|
||||
branch_name = landing_ref
|
||||
sha_commit_id = EmptyCommit().raw_id
|
||||
else:
|
||||
commit = repo.get_commit(commit_id=commit_id)
|
||||
if commit:
|
||||
branch_name = commit.branch
|
||||
|
|
@ -696,8 +700,9 @@ class RepoFilesView(RepoAppView):
|
|||
if not c.renderer:
|
||||
c.lines = filenode_as_lines_tokens(c.file)
|
||||
|
||||
_branch_name, _sha_commit_id, is_head = self._is_valid_head(
|
||||
commit_id, self.rhodecode_vcs_repo)
|
||||
_branch_name, _sha_commit_id, is_head = \
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo,
|
||||
landing_ref=self.db_repo.landing_ref_name)
|
||||
c.on_branch_head = is_head
|
||||
|
||||
branch = c.commit.branch if (
|
||||
|
|
@ -1135,7 +1140,8 @@ class RepoFilesView(RepoAppView):
|
|||
|
||||
commit_id, f_path = self._get_commit_and_path()
|
||||
_branch_name, _sha_commit_id, is_head = \
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo,
|
||||
landing_ref=self.db_repo.landing_ref_name)
|
||||
|
||||
new_path = self.request.POST.get('path')
|
||||
operation = self.request.POST.get('operation')
|
||||
|
|
@ -1173,7 +1179,8 @@ class RepoFilesView(RepoAppView):
|
|||
|
||||
self._ensure_not_locked()
|
||||
_branch_name, _sha_commit_id, is_head = \
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo,
|
||||
landing_ref=self.db_repo.landing_ref_name)
|
||||
|
||||
self.forbid_non_head(is_head, f_path)
|
||||
self.check_branch_permission(_branch_name)
|
||||
|
|
@ -1201,7 +1208,8 @@ class RepoFilesView(RepoAppView):
|
|||
|
||||
self._ensure_not_locked()
|
||||
_branch_name, _sha_commit_id, is_head = \
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo,
|
||||
landing_ref=self.db_repo.landing_ref_name)
|
||||
|
||||
self.forbid_non_head(is_head, f_path)
|
||||
self.check_branch_permission(_branch_name)
|
||||
|
|
@ -1251,7 +1259,8 @@ class RepoFilesView(RepoAppView):
|
|||
|
||||
self._ensure_not_locked()
|
||||
_branch_name, _sha_commit_id, is_head = \
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo,
|
||||
landing_ref=self.db_repo.landing_ref_name)
|
||||
|
||||
self.forbid_non_head(is_head, f_path, commit_id=commit_id)
|
||||
self.check_branch_permission(_branch_name, commit_id=commit_id)
|
||||
|
|
@ -1292,7 +1301,8 @@ class RepoFilesView(RepoAppView):
|
|||
commit_id=c.commit.raw_id, f_path=f_path))
|
||||
|
||||
_branch_name, _sha_commit_id, is_head = \
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo,
|
||||
landing_ref=self.db_repo.landing_ref_name)
|
||||
|
||||
self.forbid_non_head(is_head, f_path, commit_id=commit_id)
|
||||
self.check_branch_permission(_branch_name, commit_id=commit_id)
|
||||
|
|
@ -1380,7 +1390,8 @@ class RepoFilesView(RepoAppView):
|
|||
_branch_name, _sha_commit_id, is_head = c.commit.branch, '', True
|
||||
else:
|
||||
_branch_name, _sha_commit_id, is_head = \
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo,
|
||||
landing_ref=self.db_repo.landing_ref_name)
|
||||
|
||||
self.forbid_non_head(is_head, f_path, commit_id=commit_id)
|
||||
self.check_branch_permission(_branch_name, commit_id=commit_id)
|
||||
|
|
@ -1421,7 +1432,8 @@ class RepoFilesView(RepoAppView):
|
|||
_branch_name, _sha_commit_id, is_head = c.commit.branch, '', True
|
||||
else:
|
||||
_branch_name, _sha_commit_id, is_head = \
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo,
|
||||
landing_ref=self.db_repo.landing_ref_name)
|
||||
|
||||
self.forbid_non_head(is_head, f_path, commit_id=commit_id)
|
||||
self.check_branch_permission(_branch_name, commit_id=commit_id)
|
||||
|
|
@ -1517,7 +1529,8 @@ class RepoFilesView(RepoAppView):
|
|||
_branch_name, _sha_commit_id, is_head = c.commit.branch, '', True
|
||||
else:
|
||||
_branch_name, _sha_commit_id, is_head = \
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo)
|
||||
self._is_valid_head(commit_id, self.rhodecode_vcs_repo,
|
||||
landing_ref=self.db_repo.landing_ref_name)
|
||||
|
||||
error = self.forbid_non_head(is_head, f_path, json_mode=True)
|
||||
if error:
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class RepoSettingsPermissionsView(RepoAppView):
|
|||
c = self.load_default_context()
|
||||
c.active = 'permissions'
|
||||
if self.request.GET.get('branch_permissions'):
|
||||
h.flash(_('Explicitly add user or user group with write+ '
|
||||
h.flash(_('Explicitly add user or user group with write or higher '
|
||||
'permission to modify their branch permissions.'),
|
||||
category='notice')
|
||||
return self._get_template_context(c)
|
||||
|
|
|
|||
|
|
@ -604,68 +604,74 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
|
|||
if not force_recache and has_proper_diff_cache:
|
||||
c.diffset = cached_diff['diff']
|
||||
else:
|
||||
c.diffset = self._get_diffset(
|
||||
c.source_repo.repo_name, commits_source_repo,
|
||||
c.ancestor_commit,
|
||||
source_ref_id, target_ref_id,
|
||||
target_commit, source_commit,
|
||||
diff_limit, file_limit, c.fulldiff,
|
||||
hide_whitespace_changes, diff_context,
|
||||
use_ancestor=use_ancestor
|
||||
)
|
||||
|
||||
# save cached diff
|
||||
if caching_enabled:
|
||||
cache_diff(cache_file_path, c.diffset, diff_commit_cache)
|
||||
|
||||
c.limited_diff = c.diffset.limited_diff
|
||||
|
||||
# calculate removed files that are bound to comments
|
||||
comment_deleted_files = [
|
||||
fname for fname in display_inline_comments
|
||||
if fname not in c.diffset.file_stats]
|
||||
|
||||
c.deleted_files_comments = collections.defaultdict(dict)
|
||||
for fname, per_line_comments in display_inline_comments.items():
|
||||
if fname in comment_deleted_files:
|
||||
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)
|
||||
|
||||
# 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(
|
||||
commits_source_repo, source_repo,
|
||||
commit1, commit2, diff_limit, file_limit,
|
||||
c.fulldiff, ign_whitespace_lcl, context_lcl
|
||||
)
|
||||
try:
|
||||
c.diffset = self._get_diffset(
|
||||
c.source_repo.repo_name, commits_source_repo,
|
||||
c.ancestor_commit,
|
||||
source_ref_id, target_ref_id,
|
||||
target_commit, source_commit,
|
||||
diff_limit, file_limit, c.fulldiff,
|
||||
hide_whitespace_changes, diff_context,
|
||||
use_ancestor=use_ancestor
|
||||
)
|
||||
|
||||
# save cached diff
|
||||
if caching_enabled:
|
||||
cache_diff(range_diff_cache_file_path, diffset, None)
|
||||
cache_diff(cache_file_path, c.diffset, diff_commit_cache)
|
||||
except CommitDoesNotExistError:
|
||||
log.exception('Failed to generate diffset')
|
||||
c.missing_commits = True
|
||||
|
||||
c.changes[commit.raw_id] = diffset
|
||||
if not c.missing_commits:
|
||||
|
||||
c.limited_diff = c.diffset.limited_diff
|
||||
|
||||
# calculate removed files that are bound to comments
|
||||
comment_deleted_files = [
|
||||
fname for fname in display_inline_comments
|
||||
if fname not in c.diffset.file_stats]
|
||||
|
||||
c.deleted_files_comments = collections.defaultdict(dict)
|
||||
for fname, per_line_comments in display_inline_comments.items():
|
||||
if fname in comment_deleted_files:
|
||||
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)
|
||||
|
||||
# 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(
|
||||
commits_source_repo, 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
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ class VcsServer(object):
|
|||
else:
|
||||
if permission in self.write_perms:
|
||||
log.info(
|
||||
'WRITE+ Permissions for User "%s" detected to repo "%s"!',
|
||||
'WRITE, or Higher Permissions for User "%s" detected to repo "%s"!',
|
||||
self.user, self.repo_name)
|
||||
return 0
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -644,7 +644,7 @@ def load_rcextensions(root_path):
|
|||
rcextensions = None
|
||||
|
||||
if rcextensions:
|
||||
log.debug('Found rcextensions module loaded %s...', rcextensions)
|
||||
log.info('Loaded rcextensions from %s...', rcextensions)
|
||||
rhodecode.EXTENSIONS = rcextensions
|
||||
|
||||
# Additional mappings that are not present in the pygments lexers
|
||||
|
|
|
|||
|
|
@ -587,51 +587,17 @@ def cleaned_uri(uri):
|
|||
return urllib.quote(uri, safe='@$:/')
|
||||
|
||||
|
||||
def uri_filter(uri):
|
||||
"""
|
||||
Removes user:password from given url string
|
||||
|
||||
:param uri:
|
||||
:rtype: unicode
|
||||
:returns: filtered list of strings
|
||||
"""
|
||||
if not uri:
|
||||
return ''
|
||||
|
||||
proto = ''
|
||||
|
||||
for pat in ('https://', 'http://'):
|
||||
if uri.startswith(pat):
|
||||
uri = uri[len(pat):]
|
||||
proto = pat
|
||||
break
|
||||
|
||||
# remove passwords and username
|
||||
uri = uri[uri.find('@') + 1:]
|
||||
|
||||
# get the port
|
||||
cred_pos = uri.find(':')
|
||||
if cred_pos == -1:
|
||||
host, port = uri, None
|
||||
else:
|
||||
host, port = uri[:cred_pos], uri[cred_pos + 1:]
|
||||
|
||||
return filter(None, [proto, host, port])
|
||||
|
||||
|
||||
def credentials_filter(uri):
|
||||
"""
|
||||
Returns a url with removed credentials
|
||||
|
||||
:param uri:
|
||||
"""
|
||||
import urlobject
|
||||
url_obj = urlobject.URLObject(cleaned_uri(uri))
|
||||
url_obj = url_obj.without_password().without_username()
|
||||
|
||||
uri = uri_filter(uri)
|
||||
# check if we have port
|
||||
if len(uri) > 2 and uri[2]:
|
||||
uri[2] = ':' + uri[2]
|
||||
|
||||
return ''.join(uri)
|
||||
return url_obj
|
||||
|
||||
|
||||
def get_host_info(request):
|
||||
|
|
|
|||
|
|
@ -384,7 +384,15 @@ class EmailNotificationModel(BaseModel):
|
|||
instance_url = h.route_url('home')
|
||||
_kwargs = {
|
||||
'instance_url': instance_url,
|
||||
'whitespace_filter': self.whitespace_filter
|
||||
'whitespace_filter': self.whitespace_filter,
|
||||
'email_pr_update_subject_template': EMAIL_PR_UPDATE_SUBJECT_TEMPLATE,
|
||||
'email_pr_review_subject_template': EMAIL_PR_REVIEW_SUBJECT_TEMPLATE,
|
||||
'email_pr_comment_subject_template': EMAIL_PR_COMMENT_SUBJECT_TEMPLATE,
|
||||
'email_pr_comment_status_change_subject_template': EMAIL_PR_COMMENT_STATUS_CHANGE_SUBJECT_TEMPLATE,
|
||||
'email_pr_comment_file_subject_template': EMAIL_PR_COMMENT_FILE_SUBJECT_TEMPLATE,
|
||||
'email_comment_subject_template': EMAIL_COMMENT_SUBJECT_TEMPLATE,
|
||||
'email_comment_status_change_subject_template': EMAIL_COMMENT_STATUS_CHANGE_SUBJECT_TEMPLATE,
|
||||
'email_comment_file_subject_template': EMAIL_COMMENT_FILE_SUBJECT_TEMPLATE,
|
||||
}
|
||||
_kwargs.update(kwargs)
|
||||
return _kwargs
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ class PermissionModel(BaseModel):
|
|||
default_user_id = User.get_default_user_id()
|
||||
user_write_permissions = collections.OrderedDict()
|
||||
|
||||
# write+ and DEFAULT user for inheritance
|
||||
# write or higher and DEFAULT user for inheritance
|
||||
for perm in db_repo.permissions():
|
||||
if perm.permission in write_plus or perm.user_id == default_user_id:
|
||||
user_write_permissions[perm.user_id] = perm
|
||||
|
|
@ -571,7 +571,7 @@ class PermissionModel(BaseModel):
|
|||
write_plus = ['repository.write', 'repository.admin']
|
||||
user_group_write_permissions = collections.OrderedDict()
|
||||
|
||||
# write+ and DEFAULT user for inheritance
|
||||
# write or higher and DEFAULT user for inheritance
|
||||
for p in db_repo.permission_user_groups():
|
||||
if p.permission in write_plus:
|
||||
user_group_write_permissions[p.users_group_id] = p
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ var _TM = {
|
|||
'Collapse all files': 'Collapse all files',
|
||||
'Collapse {0} commit': 'Collapse {0} commit',
|
||||
'Collapse {0} commits': 'Collapse {0} commits',
|
||||
'Comment body was not changed.': 'Comment body was not changed.',
|
||||
'Comment text will be set automatically based on currently selected status ({0}) ...': 'Comment text will be set automatically based on currently selected status ({0}) ...',
|
||||
'Commit Authors are not allowed to be a reviewer.': 'Commit Authors are not allowed to be a reviewer.',
|
||||
'Context file: ': 'Context file: ',
|
||||
|
|
@ -112,6 +113,7 @@ var _TM = {
|
|||
'Toggle Wide Mode diff': 'Toggle Wide Mode diff',
|
||||
'Unfollow': 'Unfollow',
|
||||
'Unwatch': 'Unwatch',
|
||||
'Updated Comment': 'Updated Comment',
|
||||
'Updating...': 'Updating...',
|
||||
'User `{0}` already in reviewers': 'User `{0}` already in reviewers',
|
||||
'User `{0}` not allowed to be a reviewer': 'User `{0}` not allowed to be a reviewer',
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ var _TM = {
|
|||
'Collapse all files': 'Collapse all files',
|
||||
'Collapse {0} commit': 'Collapse {0} commit',
|
||||
'Collapse {0} commits': 'Collapse {0} commits',
|
||||
'Comment body was not changed.': 'Comment body was not changed.',
|
||||
'Comment text will be set automatically based on currently selected status ({0}) ...': 'Comment text will be set automatically based on currently selected status ({0}) ...',
|
||||
'Commit Authors are not allowed to be a reviewer.': 'Commit Authors are not allowed to be a reviewer.',
|
||||
'Context file: ': 'Context file: ',
|
||||
|
|
@ -112,6 +113,7 @@ var _TM = {
|
|||
'Toggle Wide Mode diff': 'Toggle Wide Mode diff',
|
||||
'Unfollow': 'Unfollow',
|
||||
'Unwatch': 'Unwatch',
|
||||
'Updated Comment': 'Updated Comment',
|
||||
'Updating...': 'Updating...',
|
||||
'User `{0}` already in reviewers': 'User `{0}` already in reviewers',
|
||||
'User `{0}` not allowed to be a reviewer': 'User `{0}` not allowed to be a reviewer',
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ var _TM = {
|
|||
'Collapse all files': 'Collapse all files',
|
||||
'Collapse {0} commit': 'Collapse {0} commit',
|
||||
'Collapse {0} commits': 'Collapse {0} commits',
|
||||
'Comment body was not changed.': 'Comment body was not changed.',
|
||||
'Comment text will be set automatically based on currently selected status ({0}) ...': 'Comment text will be set automatically based on currently selected status ({0}) ...',
|
||||
'Commit Authors are not allowed to be a reviewer.': 'Commit Authors are not allowed to be a reviewer.',
|
||||
'Context file: ': 'Context file: ',
|
||||
|
|
@ -112,6 +113,7 @@ var _TM = {
|
|||
'Toggle Wide Mode diff': 'Toggle Wide Mode diff',
|
||||
'Unfollow': 'Unfollow',
|
||||
'Unwatch': 'Unwatch',
|
||||
'Updated Comment': 'Updated Comment',
|
||||
'Updating...': 'Updating...',
|
||||
'User `{0}` already in reviewers': 'User `{0}` already in reviewers',
|
||||
'User `{0}` not allowed to be a reviewer': 'User `{0}` not allowed to be a reviewer',
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ var _TM = {
|
|||
'Collapse all files': 'Collapse all files',
|
||||
'Collapse {0} commit': 'Collapse {0} commit',
|
||||
'Collapse {0} commits': 'Collapse {0} commits',
|
||||
'Comment body was not changed.': 'Comment body was not changed.',
|
||||
'Comment text will be set automatically based on currently selected status ({0}) ...': 'Comment text will be set automatically based on currently selected status ({0}) ...',
|
||||
'Commit Authors are not allowed to be a reviewer.': 'Commit Authors are not allowed to be a reviewer.',
|
||||
'Context file: ': 'Context file: ',
|
||||
|
|
@ -112,6 +113,7 @@ var _TM = {
|
|||
'Toggle Wide Mode diff': 'Toggle Wide Mode diff',
|
||||
'Unfollow': 'Unfollow',
|
||||
'Unwatch': 'Unwatch',
|
||||
'Updated Comment': 'Updated Comment',
|
||||
'Updating...': 'Updating...',
|
||||
'User `{0}` already in reviewers': 'User `{0}` already in reviewers',
|
||||
'User `{0}` not allowed to be a reviewer': 'User `{0}` not allowed to be a reviewer',
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ var _TM = {
|
|||
'Collapse all files': 'Collapse all files',
|
||||
'Collapse {0} commit': 'Collapse {0} commit',
|
||||
'Collapse {0} commits': 'Collapse {0} commits',
|
||||
'Comment body was not changed.': 'Comment body was not changed.',
|
||||
'Comment text will be set automatically based on currently selected status ({0}) ...': 'Comment text will be set automatically based on currently selected status ({0}) ...',
|
||||
'Commit Authors are not allowed to be a reviewer.': 'Commit Authors are not allowed to be a reviewer.',
|
||||
'Context file: ': 'Context file: ',
|
||||
|
|
@ -112,6 +113,7 @@ var _TM = {
|
|||
'Toggle Wide Mode diff': 'Toggle Wide Mode diff',
|
||||
'Unfollow': 'Unfollow',
|
||||
'Unwatch': 'Unwatch',
|
||||
'Updated Comment': 'Updated Comment',
|
||||
'Updating...': 'Updating...',
|
||||
'User `{0}` already in reviewers': 'User `{0}` already in reviewers',
|
||||
'User `{0}` not allowed to be a reviewer': 'User `{0}` not allowed to be a reviewer',
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ var _TM = {
|
|||
'Collapse all files': 'Collapse all files',
|
||||
'Collapse {0} commit': 'Collapse {0} commit',
|
||||
'Collapse {0} commits': 'Collapse {0} commits',
|
||||
'Comment body was not changed.': 'Comment body was not changed.',
|
||||
'Comment text will be set automatically based on currently selected status ({0}) ...': 'Comment text will be set automatically based on currently selected status ({0}) ...',
|
||||
'Commit Authors are not allowed to be a reviewer.': 'Commit Authors are not allowed to be a reviewer.',
|
||||
'Context file: ': 'Context file: ',
|
||||
|
|
@ -112,6 +113,7 @@ var _TM = {
|
|||
'Toggle Wide Mode diff': 'Toggle Wide Mode diff',
|
||||
'Unfollow': 'Smetti di seguire',
|
||||
'Unwatch': 'Unwatch',
|
||||
'Updated Comment': 'Updated Comment',
|
||||
'Updating...': 'Updating...',
|
||||
'User `{0}` already in reviewers': 'User `{0}` already in reviewers',
|
||||
'User `{0}` not allowed to be a reviewer': 'User `{0}` not allowed to be a reviewer',
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ var _TM = {
|
|||
'Collapse all files': 'Collapse all files',
|
||||
'Collapse {0} commit': 'Collapse {0} commit',
|
||||
'Collapse {0} commits': 'Collapse {0} commits',
|
||||
'Comment body was not changed.': 'Comment body was not changed.',
|
||||
'Comment text will be set automatically based on currently selected status ({0}) ...': '選択したステータス ({0}) を元にコメントが自動的に設定されます...',
|
||||
'Commit Authors are not allowed to be a reviewer.': 'Commit Authors are not allowed to be a reviewer.',
|
||||
'Context file: ': 'Context file: ',
|
||||
|
|
@ -112,6 +113,7 @@ var _TM = {
|
|||
'Toggle Wide Mode diff': 'Toggle Wide Mode diff',
|
||||
'Unfollow': 'アンフォロー',
|
||||
'Unwatch': 'Unwatch',
|
||||
'Updated Comment': 'Updated Comment',
|
||||
'Updating...': 'Updating...',
|
||||
'User `{0}` already in reviewers': 'User `{0}` already in reviewers',
|
||||
'User `{0}` not allowed to be a reviewer': 'User `{0}` not allowed to be a reviewer',
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ _gettext('Close');
|
|||
_gettext('Collapse all files');
|
||||
_gettext('Collapse {0} commit');
|
||||
_gettext('Collapse {0} commits');
|
||||
_gettext('Comment body was not changed.');
|
||||
_gettext('Comment text will be set automatically based on currently selected status ({0}) ...');
|
||||
_gettext('Commit Authors are not allowed to be a reviewer.');
|
||||
_gettext('Context file: ');
|
||||
|
|
@ -106,6 +107,7 @@ _gettext('This pull requests will consist of <strong>{0} commits</strong>.');
|
|||
_gettext('Toggle Wide Mode diff');
|
||||
_gettext('Unfollow');
|
||||
_gettext('Unwatch');
|
||||
_gettext('Updated Comment');
|
||||
_gettext('Updating...');
|
||||
_gettext('User `{0}` already in reviewers');
|
||||
_gettext('User `{0}` not allowed to be a reviewer');
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ var _TM = {
|
|||
'Collapse all files': 'Collapse all files',
|
||||
'Collapse {0} commit': 'Collapse {0} commit',
|
||||
'Collapse {0} commits': 'Collapse {0} commits',
|
||||
'Comment body was not changed.': 'Comment body was not changed.',
|
||||
'Comment text will be set automatically based on currently selected status ({0}) ...': 'Comment text will be set automatically based on currently selected status ({0}) ...',
|
||||
'Commit Authors are not allowed to be a reviewer.': 'Commit Authors are not allowed to be a reviewer.',
|
||||
'Context file: ': 'Context file: ',
|
||||
|
|
@ -112,6 +113,7 @@ var _TM = {
|
|||
'Toggle Wide Mode diff': 'Toggle Wide Mode diff',
|
||||
'Unfollow': 'Nie obserwuj',
|
||||
'Unwatch': 'Unwatch',
|
||||
'Updated Comment': 'Updated Comment',
|
||||
'Updating...': 'Updating...',
|
||||
'User `{0}` already in reviewers': 'User `{0}` already in reviewers',
|
||||
'User `{0}` not allowed to be a reviewer': 'User `{0}` not allowed to be a reviewer',
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ var _TM = {
|
|||
'Collapse all files': 'Collapse all files',
|
||||
'Collapse {0} commit': 'Collapse {0} commit',
|
||||
'Collapse {0} commits': 'Collapse {0} commits',
|
||||
'Comment body was not changed.': 'Comment body was not changed.',
|
||||
'Comment text will be set automatically based on currently selected status ({0}) ...': 'Comment text will be set automatically based on currently selected status ({0}) ...',
|
||||
'Commit Authors are not allowed to be a reviewer.': 'Commit Authors are not allowed to be a reviewer.',
|
||||
'Context file: ': 'Context file: ',
|
||||
|
|
@ -112,6 +113,7 @@ var _TM = {
|
|||
'Toggle Wide Mode diff': 'Toggle Wide Mode diff',
|
||||
'Unfollow': 'Parar de seguir',
|
||||
'Unwatch': 'Unwatch',
|
||||
'Updated Comment': 'Updated Comment',
|
||||
'Updating...': 'Updating...',
|
||||
'User `{0}` already in reviewers': 'User `{0}` already in reviewers',
|
||||
'User `{0}` not allowed to be a reviewer': 'User `{0}` not allowed to be a reviewer',
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ var _TM = {
|
|||
'Collapse all files': 'Collapse all files',
|
||||
'Collapse {0} commit': 'Collapse {0} commit',
|
||||
'Collapse {0} commits': 'Collapse {0} commits',
|
||||
'Comment body was not changed.': 'Comment body was not changed.',
|
||||
'Comment text will be set automatically based on currently selected status ({0}) ...': 'Comment text will be set automatically based on currently selected status ({0}) ...',
|
||||
'Commit Authors are not allowed to be a reviewer.': 'Commit Authors are not allowed to be a reviewer.',
|
||||
'Context file: ': 'Context file: ',
|
||||
|
|
@ -112,6 +113,7 @@ var _TM = {
|
|||
'Toggle Wide Mode diff': 'Toggle Wide Mode diff',
|
||||
'Unfollow': 'Не наблюдать',
|
||||
'Unwatch': 'Unwatch',
|
||||
'Updated Comment': 'Updated Comment',
|
||||
'Updating...': 'Updating...',
|
||||
'User `{0}` already in reviewers': 'User `{0}` already in reviewers',
|
||||
'User `{0}` not allowed to be a reviewer': 'User `{0}` not allowed to be a reviewer',
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ var _TM = {
|
|||
'Collapse all files': 'Collapse all files',
|
||||
'Collapse {0} commit': 'Collapse {0} commit',
|
||||
'Collapse {0} commits': 'Collapse {0} commits',
|
||||
'Comment body was not changed.': 'Comment body was not changed.',
|
||||
'Comment text will be set automatically based on currently selected status ({0}) ...': 'Comment text will be set automatically based on currently selected status ({0}) ...',
|
||||
'Commit Authors are not allowed to be a reviewer.': 'Commit Authors are not allowed to be a reviewer.',
|
||||
'Context file: ': 'Context file: ',
|
||||
|
|
@ -112,6 +113,7 @@ var _TM = {
|
|||
'Toggle Wide Mode diff': 'Toggle Wide Mode diff',
|
||||
'Unfollow': 'Unfollow',
|
||||
'Unwatch': 'Unwatch',
|
||||
'Updated Comment': 'Updated Comment',
|
||||
'Updating...': 'Updating...',
|
||||
'User `{0}` already in reviewers': 'User `{0}` already in reviewers',
|
||||
'User `{0}` not allowed to be a reviewer': 'User `{0}` not allowed to be a reviewer',
|
||||
|
|
|
|||
|
|
@ -106,9 +106,9 @@
|
|||
|
||||
%if getattr(_user, 'branch_rules', None):
|
||||
% if used_by_n_rules == 1:
|
||||
(${_('used by {} branch rule, requires write+ permissions').format(used_by_n_rules)})
|
||||
(${_('used by {} branch rule, requires write or higher permissions').format(used_by_n_rules)})
|
||||
% else:
|
||||
(${_('used by {} branch rules, requires write+ permissions').format(used_by_n_rules)})
|
||||
(${_('used by {} branch rules, requires write or higher permissions').format(used_by_n_rules)})
|
||||
% endif
|
||||
%endif
|
||||
% endif
|
||||
|
|
|
|||
|
|
@ -465,9 +465,9 @@
|
|||
<div class="alert alert-warning">
|
||||
<div>
|
||||
<strong>${_('Missing commits')}:</strong>
|
||||
${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')}
|
||||
${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')}
|
||||
${_('Consider doing a {force_refresh_url} in case you think this is an error.').format(force_refresh_url=h.link_to('force refresh', h.current_route_path(request, force_refresh='1')))|n}
|
||||
${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')}<br/>
|
||||
${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')}<br/>
|
||||
${_('Consider doing a `force update commits` in case you think this is an error.')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -38,36 +38,29 @@ from rhodecode.lib.utils2 import AttributeDict
|
|||
from rhodecode.model.db import Repository, CacheKey
|
||||
|
||||
|
||||
def _urls_for_proto(proto):
|
||||
return [
|
||||
('%s://127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
|
||||
'%s://127.0.0.1' % proto),
|
||||
('%s://marcink@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
|
||||
'%s://127.0.0.1' % proto),
|
||||
('%s://marcink:pass@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
|
||||
'%s://127.0.0.1' % proto),
|
||||
('%s://127.0.0.1:8080' % proto, ['%s://' % proto, '127.0.0.1', '8080'],
|
||||
'%s://127.0.0.1:8080' % proto),
|
||||
('%s://domain.org' % proto, ['%s://' % proto, 'domain.org'],
|
||||
'%s://domain.org' % proto),
|
||||
('%s://user:pass@domain.org:8080' % proto,
|
||||
['%s://' % proto, 'domain.org', '8080'],
|
||||
'%s://domain.org:8080' % proto),
|
||||
TEST_URLS = [
|
||||
('127.0.0.1', '127.0.0.1'),
|
||||
('marcink@127.0.0.1', '127.0.0.1'),
|
||||
('marcink:pass@127.0.0.1', '127.0.0.1'),
|
||||
('marcink@domain.name:pass@127.0.0.1', '127.0.0.1'),
|
||||
|
||||
('127.0.0.1:8080', '127.0.0.1:8080'),
|
||||
('marcink@127.0.0.1:8080', '127.0.0.1:8080'),
|
||||
('marcink:pass@127.0.0.1:8080', '127.0.0.1:8080'),
|
||||
('marcink@domain.name:pass@127.0.0.1:8080', '127.0.0.1:8080'),
|
||||
|
||||
('domain.org', 'domain.org'),
|
||||
('user:pass@domain.org:8080', 'domain.org:8080'),
|
||||
('user@domain.org:pass@domain.org:8080', 'domain.org:8080'),
|
||||
]
|
||||
|
||||
TEST_URLS = _urls_for_proto('http') + _urls_for_proto('https')
|
||||
|
||||
|
||||
@pytest.mark.parametrize("test_url, expected, expected_creds", TEST_URLS)
|
||||
def test_uri_filter(test_url, expected, expected_creds):
|
||||
from rhodecode.lib.utils2 import uri_filter
|
||||
assert uri_filter(test_url) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("test_url, expected, expected_creds", TEST_URLS)
|
||||
def test_credentials_filter(test_url, expected, expected_creds):
|
||||
@pytest.mark.parametrize("protocol", ['http://', 'https://'])
|
||||
@pytest.mark.parametrize("test_url, expected", TEST_URLS)
|
||||
def test_credentials_filter(protocol, test_url, expected):
|
||||
from rhodecode.lib.utils2 import credentials_filter
|
||||
assert credentials_filter(test_url) == expected_creds
|
||||
test_url = protocol + test_url
|
||||
assert credentials_filter(test_url) == protocol + expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("str_bool, expected", [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue