.. _changelog:
=========
Changelog
1.3.4 (**2012-XX-XX**)
----------------------
:status: in-progress
:branch: beta
news
++++
- Whoosh logging is now controlled by the .ini files logging setup
- added clone-url into edit form on /settings page
- added help text into repo add/edit forms
- created rcextensions module with additional mappings (ref #322) and
post push/pull/create repo hooks callbacks
fixes
+++++
- fixed #390 cache invalidation problems on repos inside group
- fixed #385 clone by ID url was loosing proxy prefix in URL
- fixed some unicode problems with waitress
- fixed issue with escaping < and > in changeset commits
- fixed error occurring during recursive group creation in API
create_repo function
- fixed #393 py2.5 fixes for routes url generator
1.3.3 (**2012-03-02**)
- fixed some python2.5 compatibility issues
- fixed issues with removed repos was accidentally added as groups, after
full rescan of paths
- fixes #376 Cannot edit user (using container auth)
- fixes #378 Invalid image urls on changeset screen with proxy-prefix
configuration
- fixed initial sorting of repos inside repo group
- fixes issue when user tried to resubmit same permission into user/user_groups
- bumped beaker version that fixes #375 leap error bug
- fixed raw_changeset for git. It was generated with hg patch headers
- fixed vcs issue with last_changeset for filenodes
- fixed missing commit after hook delete
- fixed #372 issues with git operation detection that caused a security issue
for git repos
1.3.2 (**2012-02-28**)
- fixed git protocol issues with repos-groups
- fixed git remote repos validator that prevented from cloning remote git repos
- fixes #370 ending slashes fixes for repo and groups
- fixes #368 improved git-protocol detection to handle other clients
- fixes #366 When Setting Repository Group To Blank Repo Group Wont Be
Moved To Root
- fixes #371 fixed issues with beaker/sqlalchemy and non-ascii cache keys
- fixed #373 missing cascade drop on user_group_to_perm table
1.3.1 (**2012-02-27**)
- redirection loop occurs when remember-me wasn't checked during login
- fixes issues with git blob history generation
- don't fetch branch for git in file history dropdown. Causes unneeded slowness
1.3.0 (**2012-02-26**)
- code review, inspired by github code-comments
- #215 rst and markdown README files support
- #252 Container-based and proxy pass-through authentication support
- #44 branch browser. Filtering of changelog by branches
- mercurial bookmarks support
- new hover top menu, optimized to add maximum size for important views
- configurable clone url template with possibility to specify protocol like
ssh:// or http:// and also manually alter other parts of clone_url.
- enabled largefiles extension by default
- optimized summary file pages and saved a lot of unused space in them
- #239 option to manually mark repository as fork
- #320 mapping of commit authors to RhodeCode users
- #304 hashes are displayed using monospace font
- diff configuration, toggle white lines and context lines
- #307 configurable diffs, whitespace toggle, increasing context lines
- sorting on branches, tags and bookmarks using YUI datatable
- improved file filter on files page
- implements #330 api method for listing nodes ar particular revision
- #73 added linking issues in commit messages to chosen issue tracker url
based on user defined regular expression
- added linking of changesets in commit messages
- new compact changelog with expandable commit messages
- firstname and lastname are optional in user creation
- #348 added post-create repository hook
- #212 global encoding settings is now configurable from .ini files
- #227 added repository groups permissions
- markdown gets codehilite extensions
- new API methods, delete_repositories, grante/revoke permissions for groups
and repos
- rewrote dbsession management for atomic operations, and better error handling
- fixed sorting of repo tables
- #326 escape of special html entities in diffs
- normalized user_name => username in api attributes
- fixes #298 ldap created users with mixed case emails created conflicts
on saving a form
- fixes issue when owner of a repo couldn't revoke permissions for users
and groups
- fixes #271 rare JSON serialization problem with statistics
- fixes #337 missing validation check for conflicting names of a group with a
repositories group
- #340 fixed session problem for mysql and celery tasks
- fixed #331 RhodeCode mangles repository names if the a repository group
contains the "full path" to the repositories
- #355 RhodeCode doesn't store encrypted LDAP passwords
1.2.5 (**2012-01-28**)
- #340 Celery complains about MySQL server gone away, added session cleanup
for celery tasks
- #341 "scanning for repositories in None" log message during Rescan was missing
a parameter
- fixed creating archives with subrepos. Some hooks were triggered during that
operation leading to crash.
- fixed missing email in account page.
- Reverted Mercurial to 2.0.1 for windows due to bug in Mercurial that makes
forking on windows impossible
1.2.4 (**2012-01-19**)
- RhodeCode is bundled with mercurial series 2.0.X by default, with
full support to largefiles extension. Enabled by default in new installations
- #329 Ability to Add/Remove Groups to/from a Repository via AP
- added requires.txt file with requirements
- fixes db session issues with celery when emailing admins
- #331 RhodeCode mangles repository names if the a repository group
- #298 Conflicting e-mail addresses for LDAP and RhodeCode users
- DB session cleanup after hg protocol operations, fixes issues with
`mysql has gone away` errors
- #333 doc fixes for get_repo api function
- #271 rare JSON serialization problem with statistics enabled
- #337 Fixes issues with validation of repository name conflicting with
a group name. A proper message is now displayed.
- #292 made ldap_dn in user edit readonly, to get rid of confusion that field
doesn't work
- #316 fixes issues with web description in hgrc files
1.2.3 (**2011-11-02**)
- added option to manage repos group for non admin users
- added following API methods for get_users, create_user, get_users_groups,
get_users_group, create_users_group, add_user_to_users_groups, get_repos,
get_repo, create_repo, add_user_to_repo
- implements #237 added password confirmation for my account
and admin edit user.
- implements #291 email notification for global events are now sent to all
administrator users, and global config email.
- added option for passing auth method for smtp mailer
- #276 issue with adding a single user with id>10 to usergroups
- #277 fixes windows LDAP settings in which missing values breaks the ldap auth
- #288 fixes managing of repos in a group for non admin user
1.2.2 (**2011-10-17**)
- #226 repo groups are available by path instead of numerical id
- #259 Groups with the same name but with different parent group
- #260 Put repo in group, then move group to another group -> repo becomes unavailable
- #258 RhodeCode 1.2 assumes egg folder is writable (lockfiles problems)
- #265 ldap save fails sometimes on converting attributes to booleans,
added getter and setter into model that will prevent from this on db model level
- fixed problems with timestamps issues #251 and #213
- fixes #266 RhodeCode allows to create repo with the same name and in
the same parent as group
- fixes #245 Rescan of the repositories on Windows
- fixes #248 cannot edit repos inside a group on windows
- fixes #219 forking problems on windows
1.2.1 (**2011-10-08**)
- fixed problems with basic auth and push problems
- gui fixes
- fixed logger
1.2.0 (**2011-10-07**)
- implemented #47 repository groups
- implemented #89 Can setup google analytics code from settings menu
- implemented #91 added nicer looking archive urls with more download options
like tags, branches
- implemented #44 into file browsing, and added follow branch option
- implemented #84 downloads can be enabled/disabled for each repository
- anonymous repository can be cloned without having to pass default:default
into clone url
- fixed #90 whoosh indexer can index chooses repositories passed in command
line
- extended journal with day aggregates and paging
- implemented #107 source code lines highlight ranges
- implemented #93 customizable changelog on combined revision ranges -
equivalent of githubs compare view
- implemented #108 extended and more powerful LDAP configuration
- implemented #56 users groups
- major code rewrites optimized codes for speed and memory usage
- raw and diff downloads are now in git format
- setup command checks for write access to given path
- fixed many issues with international characters and unicode. It uses utf8
decode with replace to provide less errors even with non utf8 encoded strings
- #125 added API KEY access to feeds
- #109 Repository can be created from external Mercurial link (aka. remote
repository, and manually updated (via pull) from admin panel
- beta git support - push/pull server + basic view for git repos
- added followers page and forks page
- server side file creation (with binary file upload interface)
and edition with commits powered by codemirror
- #111 file browser file finder, quick lookup files on whole file tree
- added quick login sliding menu into main page
- changelog uses lazy loading of affected files details, in some scenarios
this can improve speed of changelog page dramatically especially for
larger repositories.
- implements #214 added support for downloading subrepos in download menu.
- Added basic API for direct operations on rhodecode via JSON
- Implemented advanced hook management
- fixed file browser bug, when switching into given form revision the url was
not changing
- fixed propagation to error controller on simplehg and simplegit middlewares
- fixed error when trying to make a download on empty repository
- fixed problem with '[' chars in commit messages in journal
- fixed #99 Unicode errors, on file node paths with non utf-8 characters
- journal fork fixes
- removed issue with space inside renamed repository after deletion
- fixed strange issue on formencode imports
- fixed #126 Deleting repository on Windows, rename used incompatible chars.
- #150 fixes for errors on repositories mapped in db but corrupted in
filesystem
- fixed problem with ascendant characters in realm #181
- fixed problem with sqlite file based database connection pool
- whoosh indexer and code stats share the same dynamic extensions map
- fixes #188 - relationship delete of repo_to_perm entry on user removal
- fixes issue #189 Trending source files shows "show more" when no more exist
- fixes issue #197 Relative paths for pidlocks
- fixes issue #198 password will require only 3 chars now for login form
- fixes issue #199 wrong redirection for non admin users after creating a repository
- fixes issues #202, bad db constraint made impossible to attach same group
more than one time. Affects only mysql/postgres
- fixes #218 os.kill patch for windows was missing sig param
- improved rendering of dag (they are not trimmed anymore when number of
heads exceeds 5)
1.1.8 (**2011-04-12**)
- improved windows support
- fixed #140 freeze of python dateutil library, since new version is python2.x
incompatible
- setup-app will check for write permission in given path
- cleaned up license info issue #149
- fixes for issues #137,#116 and problems with unicode and accented characters.
- fixes crashes on gravatar, when passed in email as unicode
- fixed tooltip flickering problems
- fixed came_from redirection on windows
- fixed logging modules, and sql formatters
- windows fixes for os.kill issue #133
- fixes path splitting for windows issues #148
- fixed issue #143 wrong import on migration to 1.1.X
- fixed problems with displaying binary files, thanks to Thomas Waldmann
- removed name from archive files since it's breaking ui for long repo names
- fixed issue with archive headers sent to browser, thanks to Thomas Waldmann
- fixed compatibility for 1024px displays, and larger dpi settings, thanks to
Thomas Waldmann
- fixed issue #166 summary pager was skipping 10 revisions on second page
1.1.7 (**2011-03-23**)
- fixed (again) #136 installation support for FreeBSD
1.1.6 (**2011-03-21**)
- fixed #136 installation support for FreeBSD
- RhodeCode will check for python version during installation
1.1.5 (**2011-03-17**)
- basic windows support, by exchanging pybcrypt into sha256 for windows only
highly inspired by idea of mantis406
- fixed sorting by author in main page
- fixed crashes with diffs on binary files
- fixed #131 problem with boolean values for LDAP
- fixed #122 mysql problems thanks to striker69
- fixed problem with errors on calling raw/raw_files/annotate functions
with unknown revisions
- fixed returned rawfiles attachment names with international character
- cleaned out docs, big thanks to Jason Harris
1.1.4 (**2011-02-19**)
- fixed formencode import problem on settings page, that caused server crash
when that page was accessed as first after server start
- journal fixes
- fixed option to access repository just by entering http://server/<repo_name>
# -*- coding: utf-8 -*-
"""
rhodecode.controllers.changeset
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
changeset controller for pylons showoing changes beetween
revisions
:created_on: Apr 25, 2010
:author: marcink
:copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
:license: GPLv3, see COPYING for more details.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# 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 General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import traceback
from collections import defaultdict
from webob.exc import HTTPForbidden
from pylons import tmpl_context as c, url, request, response
from pylons.i18n.translation import _
from pylons.controllers.util import redirect
from pylons.decorators import jsonify
from rhodecode.lib.vcs.exceptions import RepositoryError, ChangesetError, \
ChangesetDoesNotExistError
from rhodecode.lib.vcs.nodes import FileNode
import rhodecode.lib.helpers as h
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
from rhodecode.lib.base import BaseRepoController, render
from rhodecode.lib.utils import EmptyChangeset
from rhodecode.lib.compat import OrderedDict
from rhodecode.lib import diffs
from rhodecode.model.db import ChangesetComment
from rhodecode.model.comment import ChangesetCommentsModel
from rhodecode.model.meta import Session
from rhodecode.lib.diffs import wrapped_diff
log = logging.getLogger(__name__)
def anchor_url(revision, path):
fid = h.FID(revision, path)
return h.url.current(anchor=fid, **dict(request.GET))
def get_ignore_ws(fid, GET):
ig_ws_global = request.GET.get('ignorews')
ig_ws = filter(lambda k: k.startswith('WS'), GET.getall(fid))
if ig_ws:
try:
return int(ig_ws[0].split(':')[-1])
except:
pass
return ig_ws_global
def _ignorews_url(fileid=None):
fileid = str(fileid)
params = defaultdict(list)
lbl = _('show white space')
ig_ws = get_ignore_ws(fileid, request.GET)
ln_ctx = get_line_ctx(fileid, request.GET)
# global option
if fileid is None:
if ig_ws is None:
params['ignorews'] += [1]
lbl = _('ignore white space')
ctx_key = 'context'
ctx_val = ln_ctx
# per file options
else:
params[fileid] += ['WS:1']
ctx_key = fileid
ctx_val = 'C:%s' % ln_ctx
# if we have passed in ln_ctx pass it along to our params
if ln_ctx:
params[ctx_key] += [ctx_val]
params['anchor'] = fileid
img = h.image(h.url('/images/icons/text_strikethrough.png'), lbl, class_='icon')
return h.link_to(img, h.url.current(**params), title=lbl, class_='tooltip')
def get_line_ctx(fid, GET):
ln_ctx_global = request.GET.get('context')
ln_ctx = filter(lambda k: k.startswith('C'), GET.getall(fid))
retval = ln_ctx[0].split(':')[-1]
retval = ln_ctx_global
return int(retval)
return
def _context_url(fileid=None):
Generates url for context lines
:param fileid:
ln_ctx = (get_line_ctx(fileid, request.GET) or 3) * 2
if ln_ctx > 0:
params['context'] += [ln_ctx]
ig_ws_key = 'ignorews'
ig_ws_val = 1
# per file option
params[fileid] += ['C:%s' % ln_ctx]
ig_ws_key = fileid
ig_ws_val = 'WS:%s' % 1
params[ig_ws_key] += [ig_ws_val]
lbl = _('%s line context') % ln_ctx
img = h.image(h.url('/images/icons/table_add.png'), lbl, class_='icon')
class ChangesetController(BaseRepoController):
@LoginRequired()
@HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
'repository.admin')
def __before__(self):
super(ChangesetController, self).__before__()
c.affected_files_cut_off = 60
def index(self, revision):
c.anchor_url = anchor_url
c.ignorews_url = _ignorews_url
c.context_url = _context_url
#get ranges of revisions if preset
rev_range = revision.split('...')[:2]
enable_comments = True
if len(rev_range) == 2:
enable_comments = False
rev_start = rev_range[0]
rev_end = rev_range[1]
rev_ranges = c.rhodecode_repo.get_changesets(start=rev_start,
end=rev_end)
rev_ranges = [c.rhodecode_repo.get_changeset(revision)]
c.cs_ranges = list(rev_ranges)
if not c.cs_ranges:
raise RepositoryError('Changeset range returned empty result')
except (RepositoryError, ChangesetDoesNotExistError, Exception), e:
log.error(traceback.format_exc())
h.flash(str(e), category='warning')
return redirect(url('home'))
c.changes = OrderedDict()
c.lines_added = 0 # count of lines added
c.lines_deleted = 0 # count of lines removes
cumulative_diff = 0
c.cut_off = False # defines if cut off limit is reached
c.comments = []
c.inline_comments = []
c.inline_cnt = 0
# Iterate over ranges (default changeset view is always one changeset)
for changeset in c.cs_ranges:
c.comments.extend(ChangesetCommentsModel()\
.get_comments(c.rhodecode_db_repo.repo_id,
changeset.raw_id))
inlines = ChangesetCommentsModel()\
.get_inline_comments(c.rhodecode_db_repo.repo_id,
changeset.raw_id)
c.inline_comments.extend(inlines)
c.changes[changeset.raw_id] = []
changeset_parent = changeset.parents[0]
except IndexError:
changeset_parent = None
#==================================================================
# ADDED FILES
for node in changeset.added:
fid = h.FID(revision, node.path)
line_context_lcl = get_line_ctx(fid, request.GET)
ign_whitespace_lcl = get_ignore_ws(fid, request.GET)
lim = self.cut_off_limit
if cumulative_diff > self.cut_off_limit:
lim = -1
size, cs1, cs2, diff, st = wrapped_diff(
filenode_old=None,
filenode_new=node,
cut_off_limit=lim,
ignore_whitespace=ign_whitespace_lcl,
line_context=line_context_lcl,
enable_comments=enable_comments
)
cumulative_diff += size
c.lines_added += st[0]
c.lines_deleted += st[1]
c.changes[changeset.raw_id].append(
('added', node, diff, cs1, cs2, st)
# CHANGED FILES
for node in changeset.changed:
filenode_old = changeset_parent.get_node(node.path)
except ChangesetError:
log.warning('Unable to fetch parent node for diff')
filenode_old = FileNode(node.path, '', EmptyChangeset())
filenode_old=filenode_old,
('changed', node, diff, cs1, cs2, st)
# REMOVED FILES
for node in changeset.removed:
('removed', node, None, None, None, (0, 0))
# count inline comments
for path, lines in c.inline_comments:
for comments in lines.values():
c.inline_cnt += len(comments)
if len(c.cs_ranges) == 1:
c.changeset = c.cs_ranges[0]
c.changes = c.changes[c.changeset.raw_id]
return render('changeset/changeset.html')
return render('changeset/changeset_range.html')
def raw_changeset(self, revision):
method = request.GET.get('diff', 'show')
ignore_whitespace = request.GET.get('ignorews') == '1'
line_context = request.GET.get('context', 3)
c.scm_type = c.rhodecode_repo.alias
c.changeset = c.rhodecode_repo.get_changeset(revision)
except RepositoryError:
c.changeset_parent = c.changeset.parents[0]
c.changeset_parent = None
c.changes = []
for node in c.changeset.added:
filenode_old = FileNode(node.path, '')
if filenode_old.is_binary or node.is_binary:
diff = _('binary file') + '\n'
f_gitdiff = diffs.get_gitdiff(filenode_old, node,
ignore_whitespace=ignore_whitespace,
context=line_context)
diff = diffs.DiffProcessor(f_gitdiff,
format='gitdiff').raw_diff()
cs1 = None
cs2 = node.changeset.raw_id
c.changes.append(('added', node, diff, cs1, cs2))
for node in c.changeset.changed:
filenode_old = c.changeset_parent.get_node(node.path)
diff = _('binary file')
cs1 = filenode_old.changeset.raw_id
c.changes.append(('changed', node, diff, cs1, cs2))
response.content_type = 'text/plain'
if method == 'download':
response.content_disposition = 'attachment; filename=%s.patch' \
% revision
c.parent_tmpl = ''.join(['# Parent %s\n' % x.raw_id
for x in c.changeset.parents])
c.diffs = ''
for x in c.changes:
c.diffs += x[2]
return render('changeset/raw_changeset.html')
def comment(self, repo_name, revision):
ChangesetCommentsModel().create(text=request.POST.get('text'),
repo_id=c.rhodecode_db_repo.repo_id,
user_id=c.rhodecode_user.user_id,
revision=revision,
f_path=request.POST.get('f_path'),
line_no=request.POST.get('line'))
Session.commit()
return redirect(h.url('changeset_home', repo_name=repo_name,
revision=revision))
@jsonify
def delete_comment(self, repo_name, comment_id):
co = ChangesetComment.get(comment_id)
owner = lambda: co.author.user_id == c.rhodecode_user.user_id
if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
ChangesetCommentsModel().delete(comment=co)
return True
raise HTTPForbidden()
Status change: