diff --git a/grunt_config.json b/grunt_config.json
--- a/grunt_config.json
+++ b/grunt_config.json
@@ -68,6 +68,7 @@
"<%= dirs.js.src %>/rhodecode/utils/os.js",
"<%= dirs.js.src %>/rhodecode/utils/topics.js",
"<%= dirs.js.src %>/rhodecode/init.js",
+ "<%= dirs.js.src %>/rhodecode/changelog.js",
"<%= dirs.js.src %>/rhodecode/codemirror.js",
"<%= dirs.js.src %>/rhodecode/comments.js",
"<%= dirs.js.src %>/rhodecode/constants.js",
diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py
--- a/rhodecode/config/routing.py
+++ b/rhodecode/config/routing.py
@@ -997,10 +997,10 @@ def make_map(config):
conditions={'function': check_repo},
requirements=URL_NAME_REQUIREMENTS, jsroute=True)
- rmap.connect('changelog_details', '/{repo_name}/changelog_details/{cs}',
- controller='changelog', action='changelog_details',
+ rmap.connect('changelog_elements', '/{repo_name}/changelog_details',
+ controller='changelog', action='changelog_elements',
conditions={'function': check_repo},
- requirements=URL_NAME_REQUIREMENTS)
+ requirements=URL_NAME_REQUIREMENTS, jsroute=True)
rmap.connect('files_home', '/{repo_name}/files/{revision}/{f_path}',
controller='files', revision='tip', f_path='',
diff --git a/rhodecode/controllers/changelog.py b/rhodecode/controllers/changelog.py
--- a/rhodecode/controllers/changelog.py
+++ b/rhodecode/controllers/changelog.py
@@ -30,7 +30,8 @@ from pylons.i18n.translation import _
from webob.exc import HTTPNotFound, HTTPBadRequest
import rhodecode.lib.helpers as h
-from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
+from rhodecode.lib.auth import (
+ LoginRequired, HasRepoPermissionAnyDecorator, XHRRequired)
from rhodecode.lib.base import BaseRepoController, render
from rhodecode.lib.ext_json import json
from rhodecode.lib.graphmod import _colored, _dagwalker
@@ -98,7 +99,7 @@ class ChangelogController(BaseRepoContro
redirect(h.url('changelog_home', repo_name=repo.repo_name))
raise HTTPBadRequest()
- def _graph(self, repo, commits):
+ def _graph(self, repo, commits, prev_data=None, next_data=None):
"""
Generates a DAG graph for repo
@@ -106,12 +107,30 @@ class ChangelogController(BaseRepoContro
:param commits: list of commits
"""
if not commits:
- c.jsdata = json.dumps([])
- return
+ return json.dumps([])
+
+ def serialize(commit, parents=True):
+ data = dict(
+ raw_id=commit.raw_id,
+ idx=commit.idx,
+ branch=commit.branch,
+ )
+ if parents:
+ data['parents'] = [
+ serialize(x, parents=False) for x in commit.parents]
+ return data
+
+ prev_data = prev_data or []
+ next_data = next_data or []
+
+ current = [serialize(x) for x in commits]
+ commits = prev_data + current + next_data
dag = _dagwalker(repo, commits)
- data = [['', vtx, edges] for vtx, edges in _colored(dag)]
- c.jsdata = json.dumps(data)
+
+ data = [[commit_id, vtx, edges, branch]
+ for commit_id, vtx, edges, branch in _colored(dag)]
+ return json.dumps(data), json.dumps(current)
def _check_if_valid_branch(self, branch_name, repo_name, f_path):
if branch_name not in c.rhodecode_repo.branches_all:
@@ -120,26 +139,37 @@ class ChangelogController(BaseRepoContro
redirect(url('changelog_file_home', repo_name=repo_name,
revision=branch_name, f_path=f_path or ''))
+ def _load_changelog_data(self, collection, page, chunk_size, branch_name=None, dynamic=False):
+ c.total_cs = len(collection)
+ c.showing_commits = min(chunk_size, c.total_cs)
+ c.pagination = RepoPage(collection, page=page, item_count=c.total_cs,
+ items_per_page=chunk_size, branch=branch_name)
+
+ c.next_page = c.pagination.next_page
+ c.prev_page = c.pagination.previous_page
+
+ if dynamic:
+ if request.GET.get('chunk') != 'next':
+ c.next_page = None
+ if request.GET.get('chunk') != 'prev':
+ c.prev_page = None
+
+ page_commit_ids = [x.raw_id for x in c.pagination]
+ c.comments = c.rhodecode_db_repo.get_comments(page_commit_ids)
+ c.statuses = c.rhodecode_db_repo.statuses(page_commit_ids)
+
@LoginRequired()
@HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
'repository.admin')
def index(self, repo_name, revision=None, f_path=None):
commit_id = revision
- limit = 100
+ chunk_size = 20
+
+ c.branch_name = branch_name = request.GET.get('branch', None)
+ c.book_name = book_name = request.GET.get('bookmark', None)
hist_limit = safe_int(request.GET.get('limit')) or None
- if request.GET.get('size'):
- c.size = safe_int(request.GET.get('size'), 1)
- session['changelog_size'] = c.size
- session.save()
- else:
- c.size = int(session.get('changelog_size', DEFAULT_CHANGELOG_SIZE))
-
- # min size must be 1 and less than limit
- c.size = max(c.size, 1) if c.size <= limit else limit
p = safe_int(request.GET.get('page', 1), 1)
- c.branch_name = branch_name = request.GET.get('branch', None)
- c.book_name = book_name = request.GET.get('bookmark', None)
c.selected_name = branch_name or book_name
if not commit_id and branch_name:
@@ -147,6 +177,8 @@ class ChangelogController(BaseRepoContro
c.changelog_for_path = f_path
pre_load = ['author', 'branch', 'date', 'message', 'parents']
+ commit_ids = []
+
try:
if f_path:
log.debug('generating changelog for path %s', f_path)
@@ -174,13 +206,9 @@ class ChangelogController(BaseRepoContro
collection = c.rhodecode_repo.get_commits(
branch_name=branch_name, pre_load=pre_load)
- c.total_cs = len(collection)
- c.showing_commits = min(c.size, c.total_cs)
- c.pagination = RepoPage(collection, page=p, item_count=c.total_cs,
- items_per_page=c.size, branch=branch_name)
- page_commit_ids = [x.raw_id for x in c.pagination]
- c.comments = c.rhodecode_db_repo.get_comments(page_commit_ids)
- c.statuses = c.rhodecode_db_repo.statuses(page_commit_ids)
+ self._load_changelog_data(
+ collection, p, chunk_size, c.branch_name, dynamic=f_path)
+
except EmptyRepositoryError as e:
h.flash(safe_str(e), category='warning')
return redirect(url('summary_home', repo_name=repo_name))
@@ -195,22 +223,62 @@ class ChangelogController(BaseRepoContro
# loading from ajax, we don't want the first result, it's popped
return render('changelog/changelog_file_history.mako')
- if f_path:
- revs = []
- else:
- revs = c.pagination
- self._graph(c.rhodecode_repo, revs)
+ if not f_path:
+ commit_ids = c.pagination
+
+ c.graph_data, c.graph_commits = self._graph(
+ c.rhodecode_repo, commit_ids)
return render('changelog/changelog.mako')
@LoginRequired()
- @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
- 'repository.admin')
- def changelog_details(self, commit_id):
- if request.environ.get('HTTP_X_PARTIAL_XHR'):
- c.commit = c.rhodecode_repo.get_commit(commit_id=commit_id)
- return render('changelog/changelog_details.mako')
- raise HTTPNotFound()
+ @XHRRequired()
+ @HasRepoPermissionAnyDecorator(
+ 'repository.read', 'repository.write', 'repository.admin')
+ def changelog_elements(self, repo_name):
+ commit_id = None
+ chunk_size = 20
+
+ def wrap_for_error(err):
+ return '
ERROR: {} |
'.format(err)
+
+ c.branch_name = branch_name = request.GET.get('branch', None)
+ c.book_name = book_name = request.GET.get('bookmark', None)
+
+ p = safe_int(request.GET.get('page', 1), 1)
+
+ c.selected_name = branch_name or book_name
+ if not commit_id and branch_name:
+ if branch_name not in c.rhodecode_repo.branches_all:
+ return wrap_for_error(
+ safe_str('Missing branch: {}'.format(branch_name)))
+
+ pre_load = ['author', 'branch', 'date', 'message', 'parents']
+ collection = c.rhodecode_repo.get_commits(
+ branch_name=branch_name, pre_load=pre_load)
+
+ try:
+ self._load_changelog_data(collection, p, chunk_size, dynamic=True)
+ except EmptyRepositoryError as e:
+ return wrap_for_error(safe_str(e))
+ except (RepositoryError, CommitDoesNotExistError, Exception) as e:
+ log.exception('Failed to fetch commits')
+ return wrap_for_error(safe_str(e))
+
+ prev_data = None
+ next_data = None
+
+ prev_graph = json.loads(request.POST.get('graph', ''))
+
+ if request.GET.get('chunk') == 'prev':
+ next_data = prev_graph
+ elif request.GET.get('chunk') == 'next':
+ prev_data = prev_graph
+
+ c.graph_data, c.graph_commits = self._graph(
+ c.rhodecode_repo, c.pagination,
+ prev_data=prev_data, next_data=next_data)
+ return render('changelog/changelog_elements.mako')
@LoginRequired()
@HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
diff --git a/rhodecode/lib/graphmod.py b/rhodecode/lib/graphmod.py
--- a/rhodecode/lib/graphmod.py
+++ b/rhodecode/lib/graphmod.py
@@ -21,7 +21,7 @@
"""
Modified mercurial DAG graph functions that re-uses VCS structure
-It allows to have a shared codebase for DAG generation for hg and git repos
+It allows to have a shared codebase for DAG generation for hg, git, svn repos
"""
nullrev = -1
@@ -51,36 +51,30 @@ def _dagwalker(repo, commits):
if not commits:
return
- # TODO: johbo: Use some sort of vcs api here
- if repo.alias == 'hg':
- def get_parent_indexes(idx):
- return repo._remote.ctx_parents(idx)
+ def get_parent_indexes(idx):
+ return [commit.idx for commit in repo[idx].parents]
- elif repo.alias in ['git', 'svn']:
- def get_parent_indexes(idx):
- return [commit.idx for commit in repo[idx].parents]
-
- indexes = [commit.idx for commit in commits]
+ indexes = [commit['idx'] for commit in commits]
lowest_idx = min(indexes)
known_indexes = set(indexes)
- gpcache = {}
+ grandparnet_cache = {}
for commit in commits:
- parents = sorted(set([p.idx for p in commit.parents
- if p.idx in known_indexes]))
- mpars = [p.idx for p in commit.parents if
- p.idx != nullrev and p.idx not in parents]
+ parents = sorted(set([p['idx'] for p in commit['parents']
+ if p['idx'] in known_indexes]))
+ mpars = [p['idx'] for p in commit['parents'] if
+ p['idx'] != nullrev and p['idx'] not in parents]
for mpar in mpars:
- gp = gpcache.get(mpar)
+ gp = grandparnet_cache.get(mpar)
if gp is None:
- gp = gpcache[mpar] = grandparent(
+ gp = grandparnet_cache[mpar] = grandparent(
get_parent_indexes, lowest_idx, indexes, mpar)
if not gp:
parents.append(mpar)
else:
parents.extend(g for g in gp if g not in parents)
- yield (commit.idx, parents)
+ yield (commit['raw_id'], commit['idx'], parents, commit['branch'])
def _colored(dag):
@@ -100,7 +94,7 @@ def _colored(dag):
colors = {}
newcolor = 1
- for commit_idx, parents in dag:
+ for commit_id, commit_idx, parents, branch in dag:
# Compute seen and next_
if commit_idx not in seen:
@@ -137,7 +131,7 @@ def _colored(dag):
for p in parents])
# Yield and move on
- yield ((col, color), edges)
+ yield (commit_id, (col, color), edges, branch)
seen = next_
diff --git a/rhodecode/public/css/main.less b/rhodecode/public/css/main.less
--- a/rhodecode/public/css/main.less
+++ b/rhodecode/public/css/main.less
@@ -957,6 +957,18 @@ label {
clear: left;
}
}
+
+ .load-more-commits {
+ text-align: center;
+ }
+ .load-more-commits:hover {
+ background-color: @grey7;
+ }
+ .load-more-commits {
+ a {
+ display: block;
+ }
+ }
}
#filter_changelog {
diff --git a/rhodecode/public/css/type.less b/rhodecode/public/css/type.less
--- a/rhodecode/public/css/type.less
+++ b/rhodecode/public/css/type.less
@@ -50,7 +50,8 @@ h6, .h6 { font-size: 1em; font-family
.breadcrumbs_light {
float:left;
- margin: @padding 0;
+ font-size: 1.3em;
+ line-height: 38px;
}
// Body text
diff --git a/rhodecode/public/js/jquery.commits-graph.js b/rhodecode/public/js/jquery.commits-graph.js
--- a/rhodecode/public/js/jquery.commits-graph.js
+++ b/rhodecode/public/js/jquery.commits-graph.js
@@ -21,7 +21,7 @@ function Route( commit, data, options )
self.branch = data[2];
}
-Route.prototype.drawRoute = function ( ctx ) {
+Route.prototype.drawRoute = function ( commit, ctx ) {
var self = this;
if (self.options.orientation === "horizontal") {
@@ -52,12 +52,13 @@ Route.prototype.drawRoute = function ( c
} else {
var from_x = self.options.width * self.options.scaleFactor - (self.from + 1) * self.options.x_step * self.options.scaleFactor;
- var row = $("#chg_"+(self.commit.idx+1))
+ var row = $("#sha_" + commit.sha);
if (row.length) {
var from_y = (row.offset().top + row.height() / 2 - self.options.relaOffset) * self.options.scaleFactor;
}
var to_x = self.options.width * self.options.scaleFactor - (self.to + 1) * self.options.x_step * self.options.scaleFactor;
- var next_row = $("#chg_"+(self.commit.idx+2))
+ var next_row = $("#sha_" + commit.sha).next('tr');
+
if (next_row.length) {
var to_y = ((next_row.offset().top + next_row.height() / 2 - self.options.relaOffset) + 0.2) * self.options.scaleFactor;
}
@@ -108,7 +109,8 @@ Commit.prototype.drawDot = function ( ct
} else {
var x = self.options.width * self.options.scaleFactor - (self.dot_offset + 1) * self.options.x_step * self.options.scaleFactor;
- var row = $("#chg_"+(self.idx+1))
+ var row = $("#sha_" + self.sha);
+
var y = (row.offset().top + row.height() / 2 - self.options.relaOffset) * self.options.scaleFactor;
ctx.fillStyle = self.graph.get_color(self.dot_branch);
ctx.beginPath();
@@ -218,7 +220,7 @@ GraphCanvas.prototype.draw = function ()
ctx.lineWidth = self.options.lineWidth;
- self.options.relaOffset = $("#chg_1").offset().top;
+ self.options.relaOffset = $(".changelogRow").first().offset().top;
var n_commits = self.data.length;
for (var i=0; i.
+// #
+// # 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/
+
+
+var CommitsController = function () {
+ var self = this;
+ this.$graphCanvas = $('#graph_canvas');
+ this.$commitCounter = $('#commit-counter');
+
+ this.getCurrentGraphData = function () {
+ // raw form
+ return self.$graphCanvas.data('commits');
+ };
+
+ this.setLabelText = function (graphData) {
+ var shown = $('.commit_hash').length;
+ var total = self.$commitCounter.data('total');
+
+ if (shown == 1) {
+ var text = _gettext('showing {0} out of {1} commit').format(shown, total);
+ } else {
+ var text = _gettext('showing {0} out of {1} commits').format(shown, total);
+ }
+ self.$commitCounter.html(text)
+ };
+
+ this.reloadGraph = function (chunk) {
+ chunk = chunk || 'next';
+
+ // reset state on re-render !
+ self.$graphCanvas.html('');
+
+ var edgeData = $("[data-graph]").data('graph') || this.$graphCanvas.data('graph') || [];
+
+ // Determine max number of edges per row in graph
+ var edgeCount = 1;
+ $.each(edgeData, function (i, item) {
+ $.each(item[2], function (key, value) {
+ if (value[1] > edgeCount) {
+ edgeCount = value[1];
+ }
+ });
+ });
+
+ var x_step = Math.min(10, Math.floor(86 / edgeCount));
+ var graph_options = {
+ width: 100,
+ height: $('#changesets').find('.commits-range').height(),
+ x_step: x_step,
+ y_step: 42,
+ dotRadius: 3.5,
+ lineWidth: 2.5
+ };
+
+ var prevCommitsData = this.$graphCanvas.data('commits') || [];
+ var nextCommitsData = $("[data-graph]").data('commits') || [];
+
+ if (chunk == 'next') {
+ var commitData = $.merge(prevCommitsData, nextCommitsData);
+ } else {
+ var commitData = $.merge(nextCommitsData, prevCommitsData);
+ }
+
+ this.$graphCanvas.data('graph', edgeData);
+ this.$graphCanvas.data('commits', commitData);
+
+ // destroy dynamic loaded graph
+ $("[data-graph]").remove();
+
+ this.$graphCanvas.commits(graph_options);
+
+ this.setLabelText(edgeData);
+ if ($('.load-more-commits').find('.prev-commits').get(0)) {
+ var padding = 75;
+
+ } else {
+ var padding = 43;
+ }
+ $('#graph_nodes').css({'padding-top': padding});
+ };
+
+ this.getChunkUrl = function (page, chunk, branch) {
+ var urlData = {
+ 'repo_name': templateContext.repo_name,
+ 'page': page,
+ 'chunk': chunk
+ };
+
+ if (branch !== undefined && branch !== '') {
+ urlData['branch'] = branch;
+ }
+
+ return pyroutes.url('changelog_elements', urlData);
+ };
+
+ this.loadNext = function (node, page, branch) {
+ var loadUrl = this.getChunkUrl(page, 'next', branch);
+ var postData = {'graph': JSON.stringify(this.getCurrentGraphData())};
+
+ $.post(loadUrl, postData, function (data) {
+ $(node).closest('tbody').append(data);
+ $(node).closest('td').remove();
+ self.reloadGraph('next');
+ })
+ };
+
+ this.loadPrev = function (node, page, branch) {
+ var loadUrl = this.getChunkUrl(page, 'prev', branch);
+ var postData = {'graph': JSON.stringify(this.getCurrentGraphData())};
+
+ $.post(loadUrl, postData, function (data) {
+ $(node).closest('tbody').prepend(data);
+ $(node).closest('td').remove();
+ self.reloadGraph('prev');
+ })
+ };
+
+ this.expandCommit = function (node) {
+
+ var target_expand = $(node);
+ var cid = target_expand.data('commitId');
+
+ if (target_expand.hasClass('open')) {
+ $('#c-' + cid).css({
+ 'height': '1.5em',
+ 'white-space': 'nowrap',
+ 'text-overflow': 'ellipsis',
+ 'overflow': 'hidden'
+ });
+ $('#t-' + cid).css({
+ 'height': 'auto',
+ 'line-height': '.9em',
+ 'text-overflow': 'ellipsis',
+ 'overflow': 'hidden',
+ 'white-space': 'nowrap'
+ });
+ target_expand.removeClass('open');
+ }
+ else {
+ $('#c-' + cid).css({
+ 'height': 'auto',
+ 'white-space': 'pre-line',
+ 'text-overflow': 'initial',
+ 'overflow': 'visible'
+ });
+ $('#t-' + cid).css({
+ 'height': 'auto',
+ 'max-height': 'none',
+ 'text-overflow': 'initial',
+ 'overflow': 'visible',
+ 'white-space': 'normal'
+ });
+ target_expand.addClass('open');
+ }
+ // redraw the graph
+ self.reloadGraph();
+ }
+};
diff --git a/rhodecode/templates/changelog/changelog.mako b/rhodecode/templates/changelog/changelog.mako
--- a/rhodecode/templates/changelog/changelog.mako
+++ b/rhodecode/templates/changelog/changelog.mako
@@ -16,7 +16,6 @@
%if c.changelog_for_path:
/${c.changelog_for_path}
%endif
- ${ungettext('showing %d out of %d commit', 'showing %d out of %d commits', c.showing_commits) % (c.showing_commits, c.total_cs)}
%def>
<%def name="menu_bar_nav()">
@@ -74,6 +73,7 @@
% if c.pagination:
+
-
-
-
-
-
-
-
-
- ## checkbox
- |
- |
+
+
+
+
-
${_('Commit')} |
- ## commit message expand arrow
-
|
-
${_('Commit Message')} |
-
-
${_('Age')} |
-
${_('Author')} |
+
+
+
+ ## checkbox
+ |
+ |
- ${_('Refs')} |
-
-
- %for cnt,commit in enumerate(c.pagination):
-
-
-
- ${h.checkbox(commit.raw_id,class_="commit-range")}
- |
-
+ | ${_('Commit')} |
+ ## commit message expand arrow
+ |
+ ${_('Commit Message')} |
- %if c.statuses.get(commit.raw_id):
-
- %if c.statuses.get(commit.raw_id)[2]:
-
-
-
- %else:
-
-
-
- %endif
-
- %else:
-
- %endif
-
-
-
-
-
- ${h.show_id(commit)}
-
-
- |
-
-
-
-
- |
-
-
- ${h.urlify_commit_message(commit.message, c.repo_name)}
-
- |
+ ${_('Age')} |
+ ${_('Author')} |
+
+ ${_('Refs')} |
+
-
- ${h.age_component(commit.date)}
- |
-
- ${self.gravatar_with_user(commit.author)}
- |
-
-
- |
+
+
+
+
- ## bookmarks
- %if h.is_hg(c.rhodecode_repo):
- %for book in commit.bookmarks:
-
- ${h.shorter(book)}
-
- %endfor
- %endif
-
- ## tags
- %for tag in commit.tags:
-
- ${h.shorter(tag)}
-
- %endfor
-
-
-
-
- %endfor
-
-
-
-
-
-
-
-
-
- %else:
+
+ % else:
${_('There are no changes yet')}
- %endif
-
+ % endif
%def>
diff --git a/rhodecode/templates/changelog/changelog_details.mako b/rhodecode/templates/changelog/changelog_elements.mako
rename from rhodecode/templates/changelog/changelog_details.mako
rename to rhodecode/templates/changelog/changelog_elements.mako
--- a/rhodecode/templates/changelog/changelog_details.mako
+++ b/rhodecode/templates/changelog/changelog_elements.mako
@@ -1,11 +1,122 @@
## small box that displays changed/added/removed details fetched by AJAX
+<%namespace name="base" file="/base/base.mako"/>
+
+
+% if c.prev_page:
+
+
+
+ ${_('load previous')}
+
+ |
+
+% endif
+
+% for cnt,commit in enumerate(c.pagination):
+
+
+
+ ${h.checkbox(commit.raw_id,class_="commit-range")}
+ |
+
-% if len(c.commit.affected_files) <= c.affected_files_cut_off:
-${len(c.commit.removed)}
-${len(c.commit.changed)}
-${len(c.commit.added)}
-% else:
- !
- !
- !
+ %if c.statuses.get(commit.raw_id):
+
+ %if c.statuses.get(commit.raw_id)[2]:
+
+
+
+ %else:
+
+
+
+ %endif
+
+ %else:
+
+ %endif
+ |
+
+
+
+
+ ${h.show_id(commit)}
+
+
+ |
+
+
+
+
+ |
+
+
+ ${h.urlify_commit_message(commit.message, c.repo_name)}
+
+ |
+
+
+ ${h.age_component(commit.date)}
+ |
+
+ ${base.gravatar_with_user(commit.author)}
+ |
+
+
+
+
+ ## merge
+ %if commit.merge:
+
+ ${_('merge')}
+
+ %endif
+
+ ## branch
+ %if commit.branch:
+
+ ${h.shorter(commit.branch)}
+
+ %endif
+
+ ## bookmarks
+ %if h.is_hg(c.rhodecode_repo):
+ %for book in commit.bookmarks:
+
+ ${h.shorter(book)}
+
+ %endfor
+ %endif
+
+ ## tags
+ %for tag in commit.tags:
+
+ ${h.shorter(tag)}
+
+ %endfor
+
+
+ |
+
+% endfor
+
+% if c.next_page:
+
+
+
+ ${_('load next')}
+
+ |
+
% endif
+
+
\ No newline at end of file
diff --git a/rhodecode/templates/changelog/changelog_file_history.mako b/rhodecode/templates/changelog/changelog_file_history.mako
--- a/rhodecode/templates/changelog/changelog_file_history.mako
+++ b/rhodecode/templates/changelog/changelog_file_history.mako
@@ -14,12 +14,6 @@
-
- %if cs.merge:
-
- ${_('merge')}
-
- %endif
|