##// END OF EJS Templates
compare: rename optional compare_url parameter repo to other_repo...
Mads Kiilerich -
r3317:b36285f9 beta
parent child Browse files
Show More
@@ -1,180 +1,181 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.compare
3 rhodecode.controllers.compare
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 compare controller for pylons showing differences between two
6 compare controller for pylons showing differences between two
7 repos, branches, bookmarks or tips
7 repos, branches, bookmarks or tips
8
8
9 :created_on: May 6, 2012
9 :created_on: May 6, 2012
10 :author: marcink
10 :author: marcink
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
12 :license: GPLv3, see COPYING for more details.
12 :license: GPLv3, see COPYING for more details.
13 """
13 """
14 # This program is free software: you can redistribute it and/or modify
14 # This program is free software: you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation, either version 3 of the License, or
16 # the Free Software Foundation, either version 3 of the License, or
17 # (at your option) any later version.
17 # (at your option) any later version.
18 #
18 #
19 # This program is distributed in the hope that it will be useful,
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
22 # GNU General Public License for more details.
23 #
23 #
24 # You should have received a copy of the GNU General Public License
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 import logging
26 import logging
27 import traceback
27 import traceback
28
28
29 from webob.exc import HTTPNotFound
29 from webob.exc import HTTPNotFound
30 from pylons import request, response, session, tmpl_context as c, url
30 from pylons import request, response, session, tmpl_context as c, url
31 from pylons.controllers.util import abort, redirect
31 from pylons.controllers.util import abort, redirect
32 from pylons.i18n.translation import _
32 from pylons.i18n.translation import _
33
33
34 from rhodecode.lib.vcs.exceptions import EmptyRepositoryError, RepositoryError
34 from rhodecode.lib.vcs.exceptions import EmptyRepositoryError, RepositoryError
35 from rhodecode.lib import helpers as h
35 from rhodecode.lib import helpers as h
36 from rhodecode.lib.base import BaseRepoController, render
36 from rhodecode.lib.base import BaseRepoController, render
37 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
37 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
38 from rhodecode.lib import diffs
38 from rhodecode.lib import diffs
39
39
40 from rhodecode.model.db import Repository
40 from rhodecode.model.db import Repository
41 from rhodecode.model.pull_request import PullRequestModel
41 from rhodecode.model.pull_request import PullRequestModel
42 from webob.exc import HTTPBadRequest
42 from webob.exc import HTTPBadRequest
43 from rhodecode.lib.utils2 import str2bool
43 from rhodecode.lib.utils2 import str2bool
44 from rhodecode.lib.diffs import LimitedDiffContainer
44 from rhodecode.lib.diffs import LimitedDiffContainer
45 from rhodecode.lib.vcs.backends.base import EmptyChangeset
45 from rhodecode.lib.vcs.backends.base import EmptyChangeset
46
46
47 log = logging.getLogger(__name__)
47 log = logging.getLogger(__name__)
48
48
49
49
50 class CompareController(BaseRepoController):
50 class CompareController(BaseRepoController):
51
51
52 @LoginRequired()
52 @LoginRequired()
53 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
53 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
54 'repository.admin')
54 'repository.admin')
55 def __before__(self):
55 def __before__(self):
56 super(CompareController, self).__before__()
56 super(CompareController, self).__before__()
57
57
58 def __get_cs_or_redirect(self, rev, repo, redirect_after=True,
58 def __get_cs_or_redirect(self, rev, repo, redirect_after=True,
59 partial=False):
59 partial=False):
60 """
60 """
61 Safe way to get changeset if error occur it redirects to changeset with
61 Safe way to get changeset if error occur it redirects to changeset with
62 proper message. If partial is set then don't do redirect raise Exception
62 proper message. If partial is set then don't do redirect raise Exception
63 instead
63 instead
64
64
65 :param rev: revision to fetch
65 :param rev: revision to fetch
66 :param repo: repo instance
66 :param repo: repo instance
67 """
67 """
68
68
69 try:
69 try:
70 type_, rev = rev
70 type_, rev = rev
71 return repo.scm_instance.get_changeset(rev)
71 return repo.scm_instance.get_changeset(rev)
72 except EmptyRepositoryError, e:
72 except EmptyRepositoryError, e:
73 if not redirect_after:
73 if not redirect_after:
74 return None
74 return None
75 h.flash(h.literal(_('There are no changesets yet')),
75 h.flash(h.literal(_('There are no changesets yet')),
76 category='warning')
76 category='warning')
77 redirect(url('summary_home', repo_name=repo.repo_name))
77 redirect(url('summary_home', repo_name=repo.repo_name))
78
78
79 except RepositoryError, e:
79 except RepositoryError, e:
80 log.error(traceback.format_exc())
80 log.error(traceback.format_exc())
81 h.flash(str(e), category='warning')
81 h.flash(str(e), category='warning')
82 if not partial:
82 if not partial:
83 redirect(h.url('summary_home', repo_name=repo.repo_name))
83 redirect(h.url('summary_home', repo_name=repo.repo_name))
84 raise HTTPBadRequest()
84 raise HTTPBadRequest()
85
85
86 def index(self, org_ref_type, org_ref, other_ref_type, other_ref):
86 def index(self, org_ref_type, org_ref, other_ref_type, other_ref):
87
87
88 org_repo = c.rhodecode_db_repo.repo_name
88 org_repo = c.rhodecode_db_repo.repo_name
89 org_ref = (org_ref_type, org_ref)
89 org_ref = (org_ref_type, org_ref)
90 other_ref = (other_ref_type, other_ref)
90 other_ref = (other_ref_type, other_ref)
91 other_repo = request.GET.get('repo', org_repo)
91 other_repo = request.GET.get('other_repo', org_repo)
92 c.fulldiff = fulldiff = request.GET.get('fulldiff')
92 c.fulldiff = fulldiff = request.GET.get('fulldiff')
93 rev_start = request.GET.get('rev_start')
93 rev_start = request.GET.get('rev_start')
94 rev_end = request.GET.get('rev_end')
94 rev_end = request.GET.get('rev_end')
95
95
96 c.swap_url = h.url('compare_url', repo_name=other_repo,
96 c.swap_url = h.url('compare_url', as_form=request.GET.get('as_form'),
97 repo_name=other_repo,
97 org_ref_type=other_ref[0], org_ref=other_ref[1],
98 org_ref_type=other_ref[0], org_ref=other_ref[1],
98 other_ref_type=org_ref[0], other_ref=org_ref[1],
99 repo=org_repo,
99 repo=org_repo, as_form=request.GET.get('as_form'))
100 other_ref_type=org_ref[0], other_ref=org_ref[1])
100
101
101 c.org_repo = org_repo = Repository.get_by_repo_name(org_repo)
102 c.org_repo = org_repo = Repository.get_by_repo_name(org_repo)
102 c.other_repo = other_repo = Repository.get_by_repo_name(other_repo)
103 c.other_repo = other_repo = Repository.get_by_repo_name(other_repo)
103
104
104 if c.org_repo is None:
105 if c.org_repo is None:
105 log.error('Could not find org repo %s' % org_repo)
106 log.error('Could not find org repo %s' % org_repo)
106 raise HTTPNotFound
107 raise HTTPNotFound
107 if c.other_repo is None:
108 if c.other_repo is None:
108 log.error('Could not find other repo %s' % other_repo)
109 log.error('Could not find other repo %s' % other_repo)
109 raise HTTPNotFound
110 raise HTTPNotFound
110
111
111 if c.org_repo != c.other_repo and h.is_git(c.rhodecode_repo):
112 if c.org_repo != c.other_repo and h.is_git(c.rhodecode_repo):
112 log.error('compare of two remote repos not available for GIT REPOS')
113 log.error('compare of two remote repos not available for GIT REPOS')
113 raise HTTPNotFound
114 raise HTTPNotFound
114
115
115 if c.org_repo.scm_instance.alias != c.other_repo.scm_instance.alias:
116 if c.org_repo.scm_instance.alias != c.other_repo.scm_instance.alias:
116 log.error('compare of two different kind of remote repos not available')
117 log.error('compare of two different kind of remote repos not available')
117 raise HTTPNotFound
118 raise HTTPNotFound
118
119
119 partial = request.environ.get('HTTP_X_PARTIAL_XHR')
120 partial = request.environ.get('HTTP_X_PARTIAL_XHR')
120 self.__get_cs_or_redirect(rev=org_ref, repo=org_repo, partial=partial)
121 self.__get_cs_or_redirect(rev=org_ref, repo=org_repo, partial=partial)
121 self.__get_cs_or_redirect(rev=other_ref, repo=other_repo, partial=partial)
122 self.__get_cs_or_redirect(rev=other_ref, repo=other_repo, partial=partial)
122
123
123 if rev_start and rev_end:
124 if rev_start and rev_end:
124 #replace our org_ref with given CS
125 #replace our org_ref with given CS
125 org_ref = ('rev', rev_start)
126 org_ref = ('rev', rev_start)
126 other_ref = ('rev', rev_end)
127 other_ref = ('rev', rev_end)
127
128
128 c.cs_ranges = PullRequestModel().get_compare_data(
129 c.cs_ranges = PullRequestModel().get_compare_data(
129 org_repo, org_ref, other_repo, other_ref,
130 org_repo, org_ref, other_repo, other_ref,
130 )
131 )
131
132
132 c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in
133 c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in
133 c.cs_ranges])
134 c.cs_ranges])
134 c.target_repo = c.repo_name
135 c.target_repo = c.repo_name
135 # defines that we need hidden inputs with changesets
136 # defines that we need hidden inputs with changesets
136 c.as_form = request.GET.get('as_form', False)
137 c.as_form = request.GET.get('as_form', False)
137 if partial:
138 if partial:
138 return render('compare/compare_cs.html')
139 return render('compare/compare_cs.html')
139
140
140 c.org_ref = org_ref[1]
141 c.org_ref = org_ref[1]
141 c.other_ref = other_ref[1]
142 c.other_ref = other_ref[1]
142
143
143 if c.cs_ranges and c.org_repo != c.other_repo:
144 if c.cs_ranges and c.org_repo != c.other_repo:
144 # case we want a simple diff without incoming changesets, just
145 # case we want a simple diff without incoming changesets, just
145 # for review purposes. Make the diff on the forked repo, with
146 # for review purposes. Make the diff on the forked repo, with
146 # revision that is common ancestor
147 # revision that is common ancestor
147 _org_ref = org_ref
148 _org_ref = org_ref
148 org_ref = ('rev', getattr(c.cs_ranges[0].parents[0]
149 org_ref = ('rev', getattr(c.cs_ranges[0].parents[0]
149 if c.cs_ranges[0].parents
150 if c.cs_ranges[0].parents
150 else EmptyChangeset(), 'raw_id'))
151 else EmptyChangeset(), 'raw_id'))
151 log.debug('Changed org_ref from %s to %s' % (_org_ref, org_ref))
152 log.debug('Changed org_ref from %s to %s' % (_org_ref, org_ref))
152 other_repo = org_repo
153 other_repo = org_repo
153
154
154 diff_limit = self.cut_off_limit if not fulldiff else None
155 diff_limit = self.cut_off_limit if not fulldiff else None
155
156
156 _diff = diffs.differ(org_repo, org_ref, other_repo, other_ref)
157 _diff = diffs.differ(org_repo, org_ref, other_repo, other_ref)
157
158
158 diff_processor = diffs.DiffProcessor(_diff or '', format='gitdiff',
159 diff_processor = diffs.DiffProcessor(_diff or '', format='gitdiff',
159 diff_limit=diff_limit)
160 diff_limit=diff_limit)
160 _parsed = diff_processor.prepare()
161 _parsed = diff_processor.prepare()
161
162
162 c.limited_diff = False
163 c.limited_diff = False
163 if isinstance(_parsed, LimitedDiffContainer):
164 if isinstance(_parsed, LimitedDiffContainer):
164 c.limited_diff = True
165 c.limited_diff = True
165
166
166 c.files = []
167 c.files = []
167 c.changes = {}
168 c.changes = {}
168 c.lines_added = 0
169 c.lines_added = 0
169 c.lines_deleted = 0
170 c.lines_deleted = 0
170 for f in _parsed:
171 for f in _parsed:
171 st = f['stats']
172 st = f['stats']
172 if st[0] != 'b':
173 if st[0] != 'b':
173 c.lines_added += st[0]
174 c.lines_added += st[0]
174 c.lines_deleted += st[1]
175 c.lines_deleted += st[1]
175 fid = h.FID('', f['filename'])
176 fid = h.FID('', f['filename'])
176 c.files.append([fid, f['operation'], f['filename'], f['stats']])
177 c.files.append([fid, f['operation'], f['filename'], f['stats']])
177 diff = diff_processor.as_html(enable_comments=False, parsed_lines=[f])
178 diff = diff_processor.as_html(enable_comments=False, parsed_lines=[f])
178 c.changes[fid] = [f['operation'], f['filename'], diff]
179 c.changes[fid] = [f['operation'], f['filename'], diff]
179
180
180 return render('compare/compare_diff.html')
181 return render('compare/compare_diff.html')
@@ -1,367 +1,367 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="root.html"/>
2 <%inherit file="root.html"/>
3
3
4 <!-- HEADER -->
4 <!-- HEADER -->
5 <div id="header-dd"></div>
5 <div id="header-dd"></div>
6 <div id="header">
6 <div id="header">
7 <div id="header-inner" class="title">
7 <div id="header-inner" class="title">
8 <div id="logo">
8 <div id="logo">
9 <h1><a href="${h.url('home')}">${c.rhodecode_name}</a></h1>
9 <h1><a href="${h.url('home')}">${c.rhodecode_name}</a></h1>
10 </div>
10 </div>
11 <!-- MENU -->
11 <!-- MENU -->
12 ${self.page_nav()}
12 ${self.page_nav()}
13 <!-- END MENU -->
13 <!-- END MENU -->
14 ${self.body()}
14 ${self.body()}
15 </div>
15 </div>
16 </div>
16 </div>
17 <!-- END HEADER -->
17 <!-- END HEADER -->
18
18
19 <!-- CONTENT -->
19 <!-- CONTENT -->
20 <div id="content">
20 <div id="content">
21 <div class="flash_msg">
21 <div class="flash_msg">
22 <% messages = h.flash.pop_messages() %>
22 <% messages = h.flash.pop_messages() %>
23 % if messages:
23 % if messages:
24 <ul id="flash-messages">
24 <ul id="flash-messages">
25 % for message in messages:
25 % for message in messages:
26 <li class="${message.category}_msg">${message}</li>
26 <li class="${message.category}_msg">${message}</li>
27 % endfor
27 % endfor
28 </ul>
28 </ul>
29 % endif
29 % endif
30 </div>
30 </div>
31 <div id="main">
31 <div id="main">
32 ${next.main()}
32 ${next.main()}
33 </div>
33 </div>
34 </div>
34 </div>
35 <!-- END CONTENT -->
35 <!-- END CONTENT -->
36
36
37 <!-- FOOTER -->
37 <!-- FOOTER -->
38 <div id="footer">
38 <div id="footer">
39 <div id="footer-inner" class="title">
39 <div id="footer-inner" class="title">
40 <div>
40 <div>
41 <p class="footer-link">
41 <p class="footer-link">
42 <a href="${h.url('bugtracker')}">${_('Submit a bug')}</a>
42 <a href="${h.url('bugtracker')}">${_('Submit a bug')}</a>
43 </p>
43 </p>
44 <p class="footer-link-right">
44 <p class="footer-link-right">
45 <a href="${h.url('rhodecode_official')}">RhodeCode${'-%s' % c.rhodecode_instanceid if c.rhodecode_instanceid else ''}</a>
45 <a href="${h.url('rhodecode_official')}">RhodeCode${'-%s' % c.rhodecode_instanceid if c.rhodecode_instanceid else ''}</a>
46 ${c.rhodecode_version} &copy; 2010-${h.datetime.today().year} by Marcin Kuzminski
46 ${c.rhodecode_version} &copy; 2010-${h.datetime.today().year} by Marcin Kuzminski
47 </p>
47 </p>
48 </div>
48 </div>
49 </div>
49 </div>
50 </div>
50 </div>
51 <!-- END FOOTER -->
51 <!-- END FOOTER -->
52
52
53 ### MAKO DEFS ###
53 ### MAKO DEFS ###
54 <%def name="page_nav()">
54 <%def name="page_nav()">
55 ${self.menu()}
55 ${self.menu()}
56 </%def>
56 </%def>
57
57
58 <%def name="breadcrumbs()">
58 <%def name="breadcrumbs()">
59 <div class="breadcrumbs">
59 <div class="breadcrumbs">
60 ${self.breadcrumbs_links()}
60 ${self.breadcrumbs_links()}
61 </div>
61 </div>
62 </%def>
62 </%def>
63
63
64 <%def name="usermenu()">
64 <%def name="usermenu()">
65 ## USER MENU
65 ## USER MENU
66 <li>
66 <li>
67 <a class="menu_link" id="quick_login_link">
67 <a class="menu_link" id="quick_login_link">
68 <span class="icon" style="padding:5px 5px 0px 5px">
68 <span class="icon" style="padding:5px 5px 0px 5px">
69 <img src="${h.gravatar_url(c.rhodecode_user.email,20)}" alt="avatar">
69 <img src="${h.gravatar_url(c.rhodecode_user.email,20)}" alt="avatar">
70 </span>
70 </span>
71 %if c.rhodecode_user.username != 'default':
71 %if c.rhodecode_user.username != 'default':
72 <span class="menu_link_user">${c.rhodecode_user.username}</span>
72 <span class="menu_link_user">${c.rhodecode_user.username}</span>
73 %if c.unread_notifications != 0:
73 %if c.unread_notifications != 0:
74 <span class="menu_link_notifications">${c.unread_notifications}</span>
74 <span class="menu_link_notifications">${c.unread_notifications}</span>
75 %endif
75 %endif
76 %else:
76 %else:
77 <span>${_('Not logged in')}</span>
77 <span>${_('Not logged in')}</span>
78 %endif
78 %endif
79 </a>
79 </a>
80
80
81 <div class="user-menu">
81 <div class="user-menu">
82 <div id="quick_login">
82 <div id="quick_login">
83 %if c.rhodecode_user.username == 'default':
83 %if c.rhodecode_user.username == 'default':
84 <h4>${_('Login to your account')}</h4>
84 <h4>${_('Login to your account')}</h4>
85 ${h.form(h.url('login_home',came_from=h.url.current()))}
85 ${h.form(h.url('login_home',came_from=h.url.current()))}
86 <div class="form">
86 <div class="form">
87 <div class="fields">
87 <div class="fields">
88 <div class="field">
88 <div class="field">
89 <div class="label">
89 <div class="label">
90 <label for="username">${_('Username')}:</label>
90 <label for="username">${_('Username')}:</label>
91 </div>
91 </div>
92 <div class="input">
92 <div class="input">
93 ${h.text('username',class_='focus',size=40)}
93 ${h.text('username',class_='focus',size=40)}
94 </div>
94 </div>
95
95
96 </div>
96 </div>
97 <div class="field">
97 <div class="field">
98 <div class="label">
98 <div class="label">
99 <label for="password">${_('Password')}:</label>
99 <label for="password">${_('Password')}:</label>
100 </div>
100 </div>
101 <div class="input">
101 <div class="input">
102 ${h.password('password',class_='focus',size=40)}
102 ${h.password('password',class_='focus',size=40)}
103 </div>
103 </div>
104
104
105 </div>
105 </div>
106 <div class="buttons">
106 <div class="buttons">
107 <div class="password_forgoten">${h.link_to(_('Forgot password ?'),h.url('reset_password'))}</div>
107 <div class="password_forgoten">${h.link_to(_('Forgot password ?'),h.url('reset_password'))}</div>
108 <div class="register">
108 <div class="register">
109 %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')():
109 %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')():
110 ${h.link_to(_("Don't have an account ?"),h.url('register'))}
110 ${h.link_to(_("Don't have an account ?"),h.url('register'))}
111 %endif
111 %endif
112 </div>
112 </div>
113 <div class="submit">
113 <div class="submit">
114 ${h.submit('sign_in',_('Log In'),class_="ui-btn xsmall")}
114 ${h.submit('sign_in',_('Log In'),class_="ui-btn xsmall")}
115 </div>
115 </div>
116 </div>
116 </div>
117 </div>
117 </div>
118 </div>
118 </div>
119 ${h.end_form()}
119 ${h.end_form()}
120 %else:
120 %else:
121 <div class="links_left">
121 <div class="links_left">
122 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
122 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
123 <div class="email">${c.rhodecode_user.email}</div>
123 <div class="email">${c.rhodecode_user.email}</div>
124 <div class="big_gravatar"><img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,48)}" /></div>
124 <div class="big_gravatar"><img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,48)}" /></div>
125 <div class="notifications"><a href="${h.url('notifications')}">${_('Notifications')}</a></div>
125 <div class="notifications"><a href="${h.url('notifications')}">${_('Notifications')}</a></div>
126 <div class="unread"><a href="${h.url('notifications')}">${_('Unread')}: ${c.unread_notifications}</a></div>
126 <div class="unread"><a href="${h.url('notifications')}">${_('Unread')}: ${c.unread_notifications}</a></div>
127 </div>
127 </div>
128 <div class="links_right">
128 <div class="links_right">
129 <ol class="links">
129 <ol class="links">
130 <li>${h.link_to(_(u'Home'),h.url('home'))}</li>
130 <li>${h.link_to(_(u'Home'),h.url('home'))}</li>
131 <li>${h.link_to(_(u'Journal'),h.url('journal'))}</li>
131 <li>${h.link_to(_(u'Journal'),h.url('journal'))}</li>
132 <li>${h.link_to(_(u'My account'),h.url('admin_settings_my_account'))}</li>
132 <li>${h.link_to(_(u'My account'),h.url('admin_settings_my_account'))}</li>
133 <li class="logout">${h.link_to(_(u'Log Out'),h.url('logout_home'))}</li>
133 <li class="logout">${h.link_to(_(u'Log Out'),h.url('logout_home'))}</li>
134 </ol>
134 </ol>
135 </div>
135 </div>
136 %endif
136 %endif
137 </div>
137 </div>
138 </div>
138 </div>
139
139
140 </li>
140 </li>
141 </%def>
141 </%def>
142
142
143 <%def name="menu(current=None)">
143 <%def name="menu(current=None)">
144 <%
144 <%
145 def is_current(selected):
145 def is_current(selected):
146 if selected == current:
146 if selected == current:
147 return h.literal('class="current"')
147 return h.literal('class="current"')
148 %>
148 %>
149 <ul id="quick">
149 <ul id="quick">
150 <!-- repo switcher -->
150 <!-- repo switcher -->
151 <li ${is_current('home')}>
151 <li ${is_current('home')}>
152 <a class="menu_link" id="repo_switcher" title="${_('Switch repository')}" href="${h.url('home')}">
152 <a class="menu_link" id="repo_switcher" title="${_('Switch repository')}" href="${h.url('home')}">
153 <span class="icon">
153 <span class="icon">
154 <img src="${h.url('/images/icons/database.png')}" alt="${_('Products')}" />
154 <img src="${h.url('/images/icons/database.png')}" alt="${_('Products')}" />
155 </span>
155 </span>
156 <span>${_('Repositories')}</span>
156 <span>${_('Repositories')}</span>
157 </a>
157 </a>
158 <ul id="repo_switcher_list" class="repo_switcher">
158 <ul id="repo_switcher_list" class="repo_switcher">
159 <li>
159 <li>
160 <a href="#">${_('loading...')}</a>
160 <a href="#">${_('loading...')}</a>
161 </li>
161 </li>
162 </ul>
162 </ul>
163 </li>
163 </li>
164 ## we render this menu only not for those pages
164 ## we render this menu only not for those pages
165 %if current not in ['home','admin', 'search', 'journal']:
165 %if current not in ['home','admin', 'search', 'journal']:
166 ##REGULAR MENU
166 ##REGULAR MENU
167 <li ${is_current('summary')}>
167 <li ${is_current('summary')}>
168 <a class="menu_link" title="${_('Summary page')}" href="${h.url('summary_home',repo_name=c.repo_name)}">
168 <a class="menu_link" title="${_('Summary page')}" href="${h.url('summary_home',repo_name=c.repo_name)}">
169 <span class="icon">
169 <span class="icon">
170 <img src="${h.url('/images/icons/clipboard_16.png')}" alt="${_('Summary')}" />
170 <img src="${h.url('/images/icons/clipboard_16.png')}" alt="${_('Summary')}" />
171 </span>
171 </span>
172 <span>${_('Summary')}</span>
172 <span>${_('Summary')}</span>
173 </a>
173 </a>
174 </li>
174 </li>
175 <li ${is_current('changelog')}>
175 <li ${is_current('changelog')}>
176 <a class="menu_link" title="${_('Changeset list')}" href="${h.url('changelog_home',repo_name=c.repo_name)}">
176 <a class="menu_link" title="${_('Changeset list')}" href="${h.url('changelog_home',repo_name=c.repo_name)}">
177 <span class="icon">
177 <span class="icon">
178 <img src="${h.url('/images/icons/time.png')}" alt="${_('Changelog')}" />
178 <img src="${h.url('/images/icons/time.png')}" alt="${_('Changelog')}" />
179 </span>
179 </span>
180 <span>${_('Changelog')}</span>
180 <span>${_('Changelog')}</span>
181 </a>
181 </a>
182 </li>
182 </li>
183 <li ${is_current('switch_to')}>
183 <li ${is_current('switch_to')}>
184 <a class="menu_link" id="branch_tag_switcher" title="${_('Switch to')}" href="#">
184 <a class="menu_link" id="branch_tag_switcher" title="${_('Switch to')}" href="#">
185 <span class="icon">
185 <span class="icon">
186 <img src="${h.url('/images/icons/arrow_switch.png')}" alt="${_('Switch to')}" />
186 <img src="${h.url('/images/icons/arrow_switch.png')}" alt="${_('Switch to')}" />
187 </span>
187 </span>
188 <span>${_('Switch to')}</span>
188 <span>${_('Switch to')}</span>
189 </a>
189 </a>
190 <ul id="switch_to_list" class="switch_to">
190 <ul id="switch_to_list" class="switch_to">
191 <li><a href="#">${_('loading...')}</a></li>
191 <li><a href="#">${_('loading...')}</a></li>
192 </ul>
192 </ul>
193 </li>
193 </li>
194 <li ${is_current('files')}>
194 <li ${is_current('files')}>
195 <a class="menu_link" title="${_('Show repository content')}" href="${h.url('files_home',repo_name=c.repo_name)}">
195 <a class="menu_link" title="${_('Show repository content')}" href="${h.url('files_home',repo_name=c.repo_name)}">
196 <span class="icon">
196 <span class="icon">
197 <img src="${h.url('/images/icons/file.png')}" alt="${_('Files')}" />
197 <img src="${h.url('/images/icons/file.png')}" alt="${_('Files')}" />
198 </span>
198 </span>
199 <span>${_('Files')}</span>
199 <span>${_('Files')}</span>
200 </a>
200 </a>
201 </li>
201 </li>
202 <li ${is_current('options')}>
202 <li ${is_current('options')}>
203 <a class="menu_link" title="${_('Options')}" href="#">
203 <a class="menu_link" title="${_('Options')}" href="#">
204 <span class="icon">
204 <span class="icon">
205 <img src="${h.url('/images/icons/table_gear.png')}" alt="${_('Admin')}" />
205 <img src="${h.url('/images/icons/table_gear.png')}" alt="${_('Admin')}" />
206 </span>
206 </span>
207 <span>${_('Options')}</span>
207 <span>${_('Options')}</span>
208 </a>
208 </a>
209 <ul>
209 <ul>
210 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
210 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
211 %if h.HasPermissionAll('hg.admin')('access settings on repository'):
211 %if h.HasPermissionAll('hg.admin')('access settings on repository'):
212 <li>${h.link_to(_('repository settings'),h.url('edit_repo',repo_name=c.repo_name),class_='settings')}</li>
212 <li>${h.link_to(_('repository settings'),h.url('edit_repo',repo_name=c.repo_name),class_='settings')}</li>
213 %else:
213 %else:
214 <li>${h.link_to(_('repository settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li>
214 <li>${h.link_to(_('repository settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li>
215 %endif
215 %endif
216 %endif
216 %endif
217
217
218 <li>${h.link_to(_('fork'),h.url('repo_fork_home',repo_name=c.repo_name),class_='fork')}</li>
218 <li>${h.link_to(_('fork'),h.url('repo_fork_home',repo_name=c.repo_name),class_='fork')}</li>
219 %if h.is_hg(c.rhodecode_repo):
219 %if h.is_hg(c.rhodecode_repo):
220 <li>${h.link_to(_('open new pull request'),h.url('pullrequest_home',repo_name=c.repo_name),class_='pull_request')}</li>
220 <li>${h.link_to(_('open new pull request'),h.url('pullrequest_home',repo_name=c.repo_name),class_='pull_request')}</li>
221 %endif
221 %endif
222 %if c.rhodecode_db_repo.fork:
222 %if c.rhodecode_db_repo.fork:
223 <li>${h.link_to(_('compare fork'),h.url('compare_url',repo_name=c.repo_name,org_ref_type='branch',org_ref=request.GET.get('branch') or 'default',other_ref_type='branch',other_ref='default',repo=c.rhodecode_db_repo.fork.repo_name),class_='compare_request')}</li>
223 <li>${h.link_to(_('compare fork'),h.url('compare_url',repo_name=c.repo_name,org_ref_type='branch',org_ref=request.GET.get('branch') or 'default',other_repo=c.rhodecode_db_repo.fork.repo_name,other_ref_type='branch',other_ref='default'),class_='compare_request')}</li>
224 %endif
224 %endif
225 <li>${h.link_to(_('lightweight changelog'),h.url('shortlog_home',repo_name=c.repo_name),class_='shortlog')}</li>
225 <li>${h.link_to(_('lightweight changelog'),h.url('shortlog_home',repo_name=c.repo_name),class_='shortlog')}</li>
226 <li>${h.link_to(_('search'),h.url('search_repo',repo_name=c.repo_name),class_='search')}</li>
226 <li>${h.link_to(_('search'),h.url('search_repo',repo_name=c.repo_name),class_='search')}</li>
227
227
228 %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking:
228 %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking:
229 %if c.rhodecode_db_repo.locked[0]:
229 %if c.rhodecode_db_repo.locked[0]:
230 <li>${h.link_to(_('unlock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_del')}</li>
230 <li>${h.link_to(_('unlock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_del')}</li>
231 %else:
231 %else:
232 <li>${h.link_to(_('lock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_add')}</li>
232 <li>${h.link_to(_('lock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_add')}</li>
233 %endif
233 %endif
234 %endif
234 %endif
235
235
236 % if h.HasPermissionAll('hg.admin')('access admin main page'):
236 % if h.HasPermissionAll('hg.admin')('access admin main page'):
237 <li>
237 <li>
238 ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
238 ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
239 <%def name="admin_menu()">
239 <%def name="admin_menu()">
240 <ul>
240 <ul>
241 <li>${h.link_to(_('admin journal'),h.url('admin_home'),class_='journal')}</li>
241 <li>${h.link_to(_('admin journal'),h.url('admin_home'),class_='journal')}</li>
242 <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
242 <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
243 <li>${h.link_to(_('repositories groups'),h.url('repos_groups'),class_='repos_groups')}</li>
243 <li>${h.link_to(_('repositories groups'),h.url('repos_groups'),class_='repos_groups')}</li>
244 <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
244 <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
245 <li>${h.link_to(_('users groups'),h.url('users_groups'),class_='groups')}</li>
245 <li>${h.link_to(_('users groups'),h.url('users_groups'),class_='groups')}</li>
246 <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
246 <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
247 <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li>
247 <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li>
248 <li>${h.link_to(_('defaults'),h.url('defaults'),class_='defaults')}</li>
248 <li>${h.link_to(_('defaults'),h.url('defaults'),class_='defaults')}</li>
249 <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
249 <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
250 </ul>
250 </ul>
251 </%def>
251 </%def>
252 ## ADMIN MENU
252 ## ADMIN MENU
253 ${admin_menu()}
253 ${admin_menu()}
254 </li>
254 </li>
255 % endif
255 % endif
256 </ul>
256 </ul>
257 </li>
257 </li>
258 <li>
258 <li>
259 <a class="menu_link" title="${_('Followers')}" href="${h.url('repo_followers_home',repo_name=c.repo_name)}">
259 <a class="menu_link" title="${_('Followers')}" href="${h.url('repo_followers_home',repo_name=c.repo_name)}">
260 <span class="icon_short">
260 <span class="icon_short">
261 <img src="${h.url('/images/icons/heart.png')}" alt="${_('Followers')}" />
261 <img src="${h.url('/images/icons/heart.png')}" alt="${_('Followers')}" />
262 </span>
262 </span>
263 <span id="current_followers_count" class="short">${c.repository_followers}</span>
263 <span id="current_followers_count" class="short">${c.repository_followers}</span>
264 </a>
264 </a>
265 </li>
265 </li>
266 <li>
266 <li>
267 <a class="menu_link" title="${_('Forks')}" href="${h.url('repo_forks_home',repo_name=c.repo_name)}">
267 <a class="menu_link" title="${_('Forks')}" href="${h.url('repo_forks_home',repo_name=c.repo_name)}">
268 <span class="icon_short">
268 <span class="icon_short">
269 <img src="${h.url('/images/icons/arrow_divide.png')}" alt="${_('Forks')}" />
269 <img src="${h.url('/images/icons/arrow_divide.png')}" alt="${_('Forks')}" />
270 </span>
270 </span>
271 <span class="short">${c.repository_forks}</span>
271 <span class="short">${c.repository_forks}</span>
272 </a>
272 </a>
273 </li>
273 </li>
274 <li>
274 <li>
275 <a class="menu_link" title="${_('Pull requests')}" href="${h.url('pullrequest_show_all',repo_name=c.repo_name)}">
275 <a class="menu_link" title="${_('Pull requests')}" href="${h.url('pullrequest_show_all',repo_name=c.repo_name)}">
276 <span class="icon_short">
276 <span class="icon_short">
277 <img src="${h.url('/images/icons/arrow_join.png')}" alt="${_('Pull requests')}" />
277 <img src="${h.url('/images/icons/arrow_join.png')}" alt="${_('Pull requests')}" />
278 </span>
278 </span>
279 <span class="short">${c.repository_pull_requests}</span>
279 <span class="short">${c.repository_pull_requests}</span>
280 </a>
280 </a>
281 </li>
281 </li>
282 ${usermenu()}
282 ${usermenu()}
283 <script type="text/javascript">
283 <script type="text/javascript">
284 YUE.on('branch_tag_switcher','mouseover',function(){
284 YUE.on('branch_tag_switcher','mouseover',function(){
285 var loaded = YUD.hasClass('branch_tag_switcher','loaded');
285 var loaded = YUD.hasClass('branch_tag_switcher','loaded');
286 if(!loaded){
286 if(!loaded){
287 YUD.addClass('branch_tag_switcher','loaded');
287 YUD.addClass('branch_tag_switcher','loaded');
288 ypjax("${h.url('branch_tag_switcher',repo_name=c.repo_name)}",'switch_to_list',
288 ypjax("${h.url('branch_tag_switcher',repo_name=c.repo_name)}",'switch_to_list',
289 function(o){},
289 function(o){},
290 function(o){YUD.removeClass('branch_tag_switcher','loaded');}
290 function(o){YUD.removeClass('branch_tag_switcher','loaded');}
291 ,null);
291 ,null);
292 }
292 }
293 return false;
293 return false;
294 });
294 });
295 </script>
295 </script>
296 %else:
296 %else:
297 ##ROOT MENU
297 ##ROOT MENU
298 %if c.rhodecode_user.username != 'default':
298 %if c.rhodecode_user.username != 'default':
299 <li ${is_current('journal')}>
299 <li ${is_current('journal')}>
300 <a class="menu_link" title="${_('Show recent activity')}" href="${h.url('journal')}">
300 <a class="menu_link" title="${_('Show recent activity')}" href="${h.url('journal')}">
301 <span class="icon">
301 <span class="icon">
302 <img src="${h.url('/images/icons/book.png')}" alt="${_('Journal')}" />
302 <img src="${h.url('/images/icons/book.png')}" alt="${_('Journal')}" />
303 </span>
303 </span>
304 <span>${_('Journal')}</span>
304 <span>${_('Journal')}</span>
305 </a>
305 </a>
306 </li>
306 </li>
307 %else:
307 %else:
308 <li ${is_current('journal')}>
308 <li ${is_current('journal')}>
309 <a class="menu_link" title="${_('Public journal')}" href="${h.url('public_journal')}">
309 <a class="menu_link" title="${_('Public journal')}" href="${h.url('public_journal')}">
310 <span class="icon">
310 <span class="icon">
311 <img src="${h.url('/images/icons/book.png')}" alt="${_('Public journal')}" />
311 <img src="${h.url('/images/icons/book.png')}" alt="${_('Public journal')}" />
312 </span>
312 </span>
313 <span>${_('Public journal')}</span>
313 <span>${_('Public journal')}</span>
314 </a>
314 </a>
315 </li>
315 </li>
316 %endif
316 %endif
317 <li ${is_current('search')}>
317 <li ${is_current('search')}>
318 <a class="menu_link" title="${_('Search in repositories')}" href="${h.url('search')}">
318 <a class="menu_link" title="${_('Search in repositories')}" href="${h.url('search')}">
319 <span class="icon">
319 <span class="icon">
320 <img src="${h.url('/images/icons/search_16.png')}" alt="${_('Search')}" />
320 <img src="${h.url('/images/icons/search_16.png')}" alt="${_('Search')}" />
321 </span>
321 </span>
322 <span>${_('Search')}</span>
322 <span>${_('Search')}</span>
323 </a>
323 </a>
324 </li>
324 </li>
325 %if h.HasPermissionAll('hg.admin')('access admin main page'):
325 %if h.HasPermissionAll('hg.admin')('access admin main page'):
326 <li ${is_current('admin')}>
326 <li ${is_current('admin')}>
327 <a class="menu_link" title="${_('Admin')}" href="${h.url('admin_home')}">
327 <a class="menu_link" title="${_('Admin')}" href="${h.url('admin_home')}">
328 <span class="icon">
328 <span class="icon">
329 <img src="${h.url('/images/icons/cog_edit.png')}" alt="${_('Admin')}" />
329 <img src="${h.url('/images/icons/cog_edit.png')}" alt="${_('Admin')}" />
330 </span>
330 </span>
331 <span>${_('Admin')}</span>
331 <span>${_('Admin')}</span>
332 </a>
332 </a>
333 ${admin_menu()}
333 ${admin_menu()}
334 </li>
334 </li>
335 %endif
335 %endif
336 ${usermenu()}
336 ${usermenu()}
337 %endif
337 %endif
338 <script type="text/javascript">
338 <script type="text/javascript">
339 YUE.on('repo_switcher','mouseover',function(){
339 YUE.on('repo_switcher','mouseover',function(){
340 var target = 'q_filter_rs';
340 var target = 'q_filter_rs';
341 var qfilter_activate = function(){
341 var qfilter_activate = function(){
342 var nodes = YUQ('ul#repo_switcher_list li a.repo_name');
342 var nodes = YUQ('ul#repo_switcher_list li a.repo_name');
343 var func = function(node){
343 var func = function(node){
344 return node.parentNode;
344 return node.parentNode;
345 }
345 }
346 q_filter(target,nodes,func);
346 q_filter(target,nodes,func);
347 }
347 }
348
348
349 var loaded = YUD.hasClass('repo_switcher','loaded');
349 var loaded = YUD.hasClass('repo_switcher','loaded');
350 if(!loaded){
350 if(!loaded){
351 YUD.addClass('repo_switcher','loaded');
351 YUD.addClass('repo_switcher','loaded');
352 ypjax("${h.url('repo_switcher')}",'repo_switcher_list',
352 ypjax("${h.url('repo_switcher')}",'repo_switcher_list',
353 function(o){qfilter_activate();YUD.get(target).focus()},
353 function(o){qfilter_activate();YUD.get(target).focus()},
354 function(o){YUD.removeClass('repo_switcher','loaded');}
354 function(o){YUD.removeClass('repo_switcher','loaded');}
355 ,null);
355 ,null);
356 }else{
356 }else{
357 YUD.get(target).focus();
357 YUD.get(target).focus();
358 }
358 }
359 return false;
359 return false;
360 });
360 });
361
361
362 YUE.on('header-dd', 'click',function(e){
362 YUE.on('header-dd', 'click',function(e){
363 YUD.addClass('header-inner', 'hover');
363 YUD.addClass('header-inner', 'hover');
364 });
364 });
365
365
366 </script>
366 </script>
367 </%def>
367 </%def>
@@ -1,306 +1,306 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2
2
3 <%inherit file="/base/base.html"/>
3 <%inherit file="/base/base.html"/>
4
4
5 <%def name="title()">
5 <%def name="title()">
6 ${_('%s Changelog') % c.repo_name} - ${c.rhodecode_name}
6 ${_('%s Changelog') % c.repo_name} - ${c.rhodecode_name}
7 </%def>
7 </%def>
8
8
9 <%def name="breadcrumbs_links()">
9 <%def name="breadcrumbs_links()">
10 ${h.link_to(_(u'Home'),h.url('/'))}
10 ${h.link_to(_(u'Home'),h.url('/'))}
11 &raquo;
11 &raquo;
12 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
12 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
13 &raquo;
13 &raquo;
14 <% size = c.size if c.size <= c.total_cs else c.total_cs %>
14 <% size = c.size if c.size <= c.total_cs else c.total_cs %>
15 ${_('Changelog')} - ${ungettext('showing %d out of %d revision', 'showing %d out of %d revisions', size) % (size, c.total_cs)}
15 ${_('Changelog')} - ${ungettext('showing %d out of %d revision', 'showing %d out of %d revisions', size) % (size, c.total_cs)}
16 </%def>
16 </%def>
17
17
18 <%def name="page_nav()">
18 <%def name="page_nav()">
19 ${self.menu('changelog')}
19 ${self.menu('changelog')}
20 </%def>
20 </%def>
21
21
22 <%def name="main()">
22 <%def name="main()">
23 <div class="box">
23 <div class="box">
24 <!-- box / title -->
24 <!-- box / title -->
25 <div class="title">
25 <div class="title">
26 ${self.breadcrumbs()}
26 ${self.breadcrumbs()}
27 </div>
27 </div>
28 <div class="table">
28 <div class="table">
29 % if c.pagination:
29 % if c.pagination:
30 <div id="graph">
30 <div id="graph">
31 <div id="graph_nodes">
31 <div id="graph_nodes">
32 <canvas id="graph_canvas"></canvas>
32 <canvas id="graph_canvas"></canvas>
33 </div>
33 </div>
34 <div id="graph_content">
34 <div id="graph_content">
35 <div class="info_box" style="clear: both;padding: 10px 6px;vertical-align: right;text-align: right;">
35 <div class="info_box" style="clear: both;padding: 10px 6px;vertical-align: right;text-align: right;">
36 <a href="#" class="ui-btn small" id="rev_range_container" style="display:none"></a>
36 <a href="#" class="ui-btn small" id="rev_range_container" style="display:none"></a>
37 <a href="#" class="ui-btn small" id="rev_range_clear" style="display:none">${_('Clear selection')}</a>
37 <a href="#" class="ui-btn small" id="rev_range_clear" style="display:none">${_('Clear selection')}</a>
38
38
39 %if c.rhodecode_db_repo.fork:
39 %if c.rhodecode_db_repo.fork:
40 <a title="${_('compare fork with %s' % c.rhodecode_db_repo.fork.repo_name)}" href="${h.url('compare_url',repo_name=c.repo_name,org_ref_type='branch',org_ref=request.GET.get('branch') or 'default',other_ref_type='branch',other_ref='default',repo=c.rhodecode_db_repo.fork.repo_name)}" class="ui-btn small">${_('Compare fork with parent')}</a>
40 <a title="${_('compare fork with %s' % c.rhodecode_db_repo.fork.repo_name)}" href="${h.url('compare_url',repo_name=c.repo_name,org_ref_type='branch',org_ref=request.GET.get('branch') or 'default',other_repo=c.rhodecode_db_repo.fork.repo_name,other_ref_type='branch',other_ref='default')}" class="ui-btn small">${_('Compare fork with parent')}</a>
41 %endif
41 %endif
42 %if h.is_hg(c.rhodecode_repo):
42 %if h.is_hg(c.rhodecode_repo):
43 <a id="open_new_pr" href="${h.url('pullrequest_home',repo_name=c.repo_name)}" class="ui-btn small">${_('open new pull request')}</a>
43 <a id="open_new_pr" href="${h.url('pullrequest_home',repo_name=c.repo_name)}" class="ui-btn small">${_('open new pull request')}</a>
44 %endif
44 %endif
45 </div>
45 </div>
46 <div class="container_header">
46 <div class="container_header">
47 ${h.form(h.url.current(),method='get')}
47 ${h.form(h.url.current(),method='get')}
48 <div class="info_box" style="float:left">
48 <div class="info_box" style="float:left">
49 ${h.submit('set',_('Show'),class_="ui-btn")}
49 ${h.submit('set',_('Show'),class_="ui-btn")}
50 ${h.text('size',size=1,value=c.size)}
50 ${h.text('size',size=1,value=c.size)}
51 ${_('revisions')}
51 ${_('revisions')}
52 </div>
52 </div>
53 ${h.end_form()}
53 ${h.end_form()}
54 <div style="float:right">${h.select('branch_filter',c.branch_name,c.branch_filters)}</div>
54 <div style="float:right">${h.select('branch_filter',c.branch_name,c.branch_filters)}</div>
55 </div>
55 </div>
56
56
57 %for cnt,cs in enumerate(c.pagination):
57 %for cnt,cs in enumerate(c.pagination):
58 <div id="chg_${cnt+1}" class="container ${'tablerow%s' % (cnt%2)}">
58 <div id="chg_${cnt+1}" class="container ${'tablerow%s' % (cnt%2)}">
59 <div class="left">
59 <div class="left">
60 <div>
60 <div>
61 ${h.checkbox(cs.raw_id,class_="changeset_range")}
61 ${h.checkbox(cs.raw_id,class_="changeset_range")}
62 <span class="tooltip" title="${h.tooltip(h.age(cs.date))}"><a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id)}"><span class="changeset_id">${cs.revision}:<span class="changeset_hash">${h.short_id(cs.raw_id)}</span></span></a></span>
62 <span class="tooltip" title="${h.tooltip(h.age(cs.date))}"><a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id)}"><span class="changeset_id">${cs.revision}:<span class="changeset_hash">${h.short_id(cs.raw_id)}</span></span></a></span>
63 </div>
63 </div>
64 <div class="author">
64 <div class="author">
65 <div class="gravatar">
65 <div class="gravatar">
66 <img alt="gravatar" src="${h.gravatar_url(h.email_or_none(cs.author),16)}"/>
66 <img alt="gravatar" src="${h.gravatar_url(h.email_or_none(cs.author),16)}"/>
67 </div>
67 </div>
68 <div title="${cs.author}" class="user">${h.shorter(h.person(cs.author),22)}</div>
68 <div title="${cs.author}" class="user">${h.shorter(h.person(cs.author),22)}</div>
69 </div>
69 </div>
70 <div class="date">${h.fmt_date(cs.date)}</div>
70 <div class="date">${h.fmt_date(cs.date)}</div>
71 </div>
71 </div>
72 <div class="mid">
72 <div class="mid">
73 <div class="message">${h.urlify_commit(cs.message, c.repo_name,h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div>
73 <div class="message">${h.urlify_commit(cs.message, c.repo_name,h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div>
74 <div class="expand"><span class="expandtext">&darr; ${_('show more')} &darr;</span></div>
74 <div class="expand"><span class="expandtext">&darr; ${_('show more')} &darr;</span></div>
75 </div>
75 </div>
76 <div class="right">
76 <div class="right">
77 <div class="changes">
77 <div class="changes">
78 <div id="changed_total_${cs.raw_id}" style="float:right;" class="changed_total tooltip" title="${h.tooltip(_('Affected number of files, click to show more details'))}">${len(cs.affected_files)}</div>
78 <div id="changed_total_${cs.raw_id}" style="float:right;" class="changed_total tooltip" title="${h.tooltip(_('Affected number of files, click to show more details'))}">${len(cs.affected_files)}</div>
79 <div class="comments-container">
79 <div class="comments-container">
80 %if len(c.comments.get(cs.raw_id,[])) > 0:
80 %if len(c.comments.get(cs.raw_id,[])) > 0:
81 <div class="comments-cnt" title="${('comments')}">
81 <div class="comments-cnt" title="${('comments')}">
82 <a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id,anchor='comment-%s' % c.comments[cs.raw_id][0].comment_id)}">
82 <a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id,anchor='comment-%s' % c.comments[cs.raw_id][0].comment_id)}">
83 <div class="comments-cnt">${len(c.comments[cs.raw_id])}</div>
83 <div class="comments-cnt">${len(c.comments[cs.raw_id])}</div>
84 <img src="${h.url('/images/icons/comments.png')}">
84 <img src="${h.url('/images/icons/comments.png')}">
85 </a>
85 </a>
86 </div>
86 </div>
87 %endif
87 %endif
88 </div>
88 </div>
89 <div class="changeset-status-container">
89 <div class="changeset-status-container">
90 %if c.statuses.get(cs.raw_id):
90 %if c.statuses.get(cs.raw_id):
91 <div title="${_('Changeset status')}" class="changeset-status-lbl">${c.statuses.get(cs.raw_id)[1]}</div>
91 <div title="${_('Changeset status')}" class="changeset-status-lbl">${c.statuses.get(cs.raw_id)[1]}</div>
92 <div class="changeset-status-ico">
92 <div class="changeset-status-ico">
93 %if c.statuses.get(cs.raw_id)[2]:
93 %if c.statuses.get(cs.raw_id)[2]:
94 <a class="tooltip" title="${_('Click to open associated pull request #%s' % c.statuses.get(cs.raw_id)[2])}" href="${h.url('pullrequest_show',repo_name=c.statuses.get(cs.raw_id)[3],pull_request_id=c.statuses.get(cs.raw_id)[2])}"><img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" /></a>
94 <a class="tooltip" title="${_('Click to open associated pull request #%s' % c.statuses.get(cs.raw_id)[2])}" href="${h.url('pullrequest_show',repo_name=c.statuses.get(cs.raw_id)[3],pull_request_id=c.statuses.get(cs.raw_id)[2])}"><img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" /></a>
95 %else:
95 %else:
96 <img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" />
96 <img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" />
97 %endif
97 %endif
98 </div>
98 </div>
99 %endif
99 %endif
100 </div>
100 </div>
101 </div>
101 </div>
102 %if cs.parents:
102 %if cs.parents:
103 %for p_cs in reversed(cs.parents):
103 %for p_cs in reversed(cs.parents):
104 <div class="parent">${_('Parent')}
104 <div class="parent">${_('Parent')}
105 <span class="changeset_id">${p_cs.revision}:<span class="changeset_hash">${h.link_to(h.short_id(p_cs.raw_id),
105 <span class="changeset_id">${p_cs.revision}:<span class="changeset_hash">${h.link_to(h.short_id(p_cs.raw_id),
106 h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}</span></span>
106 h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}</span></span>
107 </div>
107 </div>
108 %endfor
108 %endfor
109 %else:
109 %else:
110 <div class="parent">${_('No parents')}</div>
110 <div class="parent">${_('No parents')}</div>
111 %endif
111 %endif
112
112
113 <span class="logtags">
113 <span class="logtags">
114 %if len(cs.parents)>1:
114 %if len(cs.parents)>1:
115 <span class="merge">${_('merge')}</span>
115 <span class="merge">${_('merge')}</span>
116 %endif
116 %endif
117 %if cs.branch:
117 %if cs.branch:
118 <span class="branchtag" title="${'%s %s' % (_('branch'),cs.branch)}">
118 <span class="branchtag" title="${'%s %s' % (_('branch'),cs.branch)}">
119 ${h.link_to(h.shorter(cs.branch),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
119 ${h.link_to(h.shorter(cs.branch),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
120 </span>
120 </span>
121 %endif
121 %endif
122 %if h.is_hg(c.rhodecode_repo):
122 %if h.is_hg(c.rhodecode_repo):
123 %for book in cs.bookmarks:
123 %for book in cs.bookmarks:
124 <span class="bookbook" title="${'%s %s' % (_('bookmark'),book)}">
124 <span class="bookbook" title="${'%s %s' % (_('bookmark'),book)}">
125 ${h.link_to(h.shorter(book),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
125 ${h.link_to(h.shorter(book),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
126 </span>
126 </span>
127 %endfor
127 %endfor
128 %endif
128 %endif
129 %for tag in cs.tags:
129 %for tag in cs.tags:
130 <span class="tagtag" title="${'%s %s' % (_('tag'),tag)}">
130 <span class="tagtag" title="${'%s %s' % (_('tag'),tag)}">
131 ${h.link_to(h.shorter(tag),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}</span>
131 ${h.link_to(h.shorter(tag),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}</span>
132 %endfor
132 %endfor
133 </span>
133 </span>
134 </div>
134 </div>
135 </div>
135 </div>
136
136
137 %endfor
137 %endfor
138 <div class="pagination-wh pagination-left">
138 <div class="pagination-wh pagination-left">
139 ${c.pagination.pager('$link_previous ~2~ $link_next')}
139 ${c.pagination.pager('$link_previous ~2~ $link_next')}
140 </div>
140 </div>
141 </div>
141 </div>
142 </div>
142 </div>
143
143
144 <script type="text/javascript" src="${h.url('/js/graph.js')}"></script>
144 <script type="text/javascript" src="${h.url('/js/graph.js')}"></script>
145 <script type="text/javascript">
145 <script type="text/javascript">
146 YAHOO.util.Event.onDOMReady(function(){
146 YAHOO.util.Event.onDOMReady(function(){
147
147
148 //Monitor range checkboxes and build a link to changesets
148 //Monitor range checkboxes and build a link to changesets
149 //ranges
149 //ranges
150 var checkboxes = YUD.getElementsByClassName('changeset_range');
150 var checkboxes = YUD.getElementsByClassName('changeset_range');
151 var url_tmpl = "${h.url('changeset_home',repo_name=c.repo_name,revision='__REVRANGE__')}";
151 var url_tmpl = "${h.url('changeset_home',repo_name=c.repo_name,revision='__REVRANGE__')}";
152 var pr_tmpl = "${h.url('pullrequest_home',repo_name=c.repo_name)}";
152 var pr_tmpl = "${h.url('pullrequest_home',repo_name=c.repo_name)}";
153 YUE.on(checkboxes,'click',function(e){
153 YUE.on(checkboxes,'click',function(e){
154 var clicked_cb = e.currentTarget;
154 var clicked_cb = e.currentTarget;
155 var checked_checkboxes = [];
155 var checked_checkboxes = [];
156 for (pos in checkboxes){
156 for (pos in checkboxes){
157 if(checkboxes[pos].checked){
157 if(checkboxes[pos].checked){
158 checked_checkboxes.push(checkboxes[pos]);
158 checked_checkboxes.push(checkboxes[pos]);
159 }
159 }
160 }
160 }
161 if(YUD.get('open_new_pr')){
161 if(YUD.get('open_new_pr')){
162 if(checked_checkboxes.length>0){
162 if(checked_checkboxes.length>0){
163 // modify open pull request to show we have selected cs
163 // modify open pull request to show we have selected cs
164 YUD.get('open_new_pr').innerHTML = _TM['Open new pull request for selected changesets'];
164 YUD.get('open_new_pr').innerHTML = _TM['Open new pull request for selected changesets'];
165
165
166 }else{
166 }else{
167 YUD.get('open_new_pr').innerHTML = _TM['Open new pull request'];
167 YUD.get('open_new_pr').innerHTML = _TM['Open new pull request'];
168 }
168 }
169 }
169 }
170
170
171 if(checked_checkboxes.length>0){
171 if(checked_checkboxes.length>0){
172 var rev_end = checked_checkboxes[0].name;
172 var rev_end = checked_checkboxes[0].name;
173 var rev_start = checked_checkboxes[checked_checkboxes.length-1].name;
173 var rev_start = checked_checkboxes[checked_checkboxes.length-1].name;
174
174
175 // now select all checkboxes in the middle.
175 // now select all checkboxes in the middle.
176 var checked = false;
176 var checked = false;
177 for (var i=0; i<checkboxes.length; i++){
177 for (var i=0; i<checkboxes.length; i++){
178 var cb = checkboxes[i];
178 var cb = checkboxes[i];
179 var rev = cb.name;
179 var rev = cb.name;
180
180
181 if (rev == rev_end){
181 if (rev == rev_end){
182 checked = true;
182 checked = true;
183 }
183 }
184 if (checked){
184 if (checked){
185 cb.checked = true;
185 cb.checked = true;
186 }
186 }
187 else{
187 else{
188 cb.checked = false;
188 cb.checked = false;
189 }
189 }
190 if (rev == rev_start){
190 if (rev == rev_start){
191 checked = false;
191 checked = false;
192 }
192 }
193
193
194 }
194 }
195
195
196 var url = url_tmpl.replace('__REVRANGE__',
196 var url = url_tmpl.replace('__REVRANGE__',
197 rev_start+'...'+rev_end);
197 rev_start+'...'+rev_end);
198
198
199 var link = _TM['Show selected changes __S -> __E'];
199 var link = _TM['Show selected changes __S -> __E'];
200 link = link.replace('__S',rev_start.substr(0,6));
200 link = link.replace('__S',rev_start.substr(0,6));
201 link = link.replace('__E',rev_end.substr(0,6));
201 link = link.replace('__E',rev_end.substr(0,6));
202 YUD.get('rev_range_container').href = url;
202 YUD.get('rev_range_container').href = url;
203 YUD.get('rev_range_container').innerHTML = link;
203 YUD.get('rev_range_container').innerHTML = link;
204 YUD.setStyle('rev_range_container','display','');
204 YUD.setStyle('rev_range_container','display','');
205 YUD.setStyle('rev_range_clear','display','');
205 YUD.setStyle('rev_range_clear','display','');
206
206
207 YUD.get('open_new_pr').href = pr_tmpl + '?rev_start={0}&rev_end={1}'.format(rev_start,rev_end);
207 YUD.get('open_new_pr').href = pr_tmpl + '?rev_start={0}&rev_end={1}'.format(rev_start,rev_end);
208
208
209 }
209 }
210 else{
210 else{
211 YUD.setStyle('rev_range_container','display','none');
211 YUD.setStyle('rev_range_container','display','none');
212 YUD.setStyle('rev_range_clear','display','none');
212 YUD.setStyle('rev_range_clear','display','none');
213 }
213 }
214 });
214 });
215 YUE.on('rev_range_clear','click',function(e){
215 YUE.on('rev_range_clear','click',function(e){
216 for (var i=0; i<checkboxes.length; i++){
216 for (var i=0; i<checkboxes.length; i++){
217 var cb = checkboxes[i];
217 var cb = checkboxes[i];
218 cb.checked = false;
218 cb.checked = false;
219 }
219 }
220 YUE.preventDefault(e);
220 YUE.preventDefault(e);
221 })
221 })
222 var msgs = YUQ('.message');
222 var msgs = YUQ('.message');
223 // get first element height
223 // get first element height
224 var el = YUQ('#graph_content .container')[0];
224 var el = YUQ('#graph_content .container')[0];
225 var row_h = el.clientHeight;
225 var row_h = el.clientHeight;
226 for(var i=0;i<msgs.length;i++){
226 for(var i=0;i<msgs.length;i++){
227 var m = msgs[i];
227 var m = msgs[i];
228
228
229 var h = m.clientHeight;
229 var h = m.clientHeight;
230 var pad = YUD.getStyle(m,'padding');
230 var pad = YUD.getStyle(m,'padding');
231 if(h > row_h){
231 if(h > row_h){
232 var offset = row_h - (h+12);
232 var offset = row_h - (h+12);
233 YUD.setStyle(m.nextElementSibling,'display','block');
233 YUD.setStyle(m.nextElementSibling,'display','block');
234 YUD.setStyle(m.nextElementSibling,'margin-top',offset+'px');
234 YUD.setStyle(m.nextElementSibling,'margin-top',offset+'px');
235 };
235 };
236 }
236 }
237 YUE.on(YUQ('.expand'),'click',function(e){
237 YUE.on(YUQ('.expand'),'click',function(e){
238 var elem = e.currentTarget.parentNode.parentNode;
238 var elem = e.currentTarget.parentNode.parentNode;
239 YUD.setStyle(e.currentTarget,'display','none');
239 YUD.setStyle(e.currentTarget,'display','none');
240 YUD.setStyle(elem,'height','auto');
240 YUD.setStyle(elem,'height','auto');
241
241
242 //redraw the graph, line_count and jsdata are global vars
242 //redraw the graph, line_count and jsdata are global vars
243 set_canvas(100);
243 set_canvas(100);
244
244
245 var r = new BranchRenderer();
245 var r = new BranchRenderer();
246 r.render(jsdata,100,line_count);
246 r.render(jsdata,100,line_count);
247
247
248 })
248 })
249
249
250 // Fetch changeset details
250 // Fetch changeset details
251 YUE.on(YUD.getElementsByClassName('changed_total'),'click',function(e){
251 YUE.on(YUD.getElementsByClassName('changed_total'),'click',function(e){
252 var id = e.currentTarget.id;
252 var id = e.currentTarget.id;
253 var url = "${h.url('changelog_details',repo_name=c.repo_name,cs='__CS__')}";
253 var url = "${h.url('changelog_details',repo_name=c.repo_name,cs='__CS__')}";
254 var url = url.replace('__CS__',id.replace('changed_total_',''));
254 var url = url.replace('__CS__',id.replace('changed_total_',''));
255 ypjax(url,id,function(){tooltip_activate()});
255 ypjax(url,id,function(){tooltip_activate()});
256 });
256 });
257
257
258 // change branch filter
258 // change branch filter
259 YUE.on(YUD.get('branch_filter'),'change',function(e){
259 YUE.on(YUD.get('branch_filter'),'change',function(e){
260 var selected_branch = e.currentTarget.options[e.currentTarget.selectedIndex].value;
260 var selected_branch = e.currentTarget.options[e.currentTarget.selectedIndex].value;
261 var url_main = "${h.url('changelog_home',repo_name=c.repo_name)}";
261 var url_main = "${h.url('changelog_home',repo_name=c.repo_name)}";
262 var url = "${h.url('changelog_home',repo_name=c.repo_name,branch='__BRANCH__')}";
262 var url = "${h.url('changelog_home',repo_name=c.repo_name,branch='__BRANCH__')}";
263 var url = url.replace('__BRANCH__',selected_branch);
263 var url = url.replace('__BRANCH__',selected_branch);
264 if(selected_branch != ''){
264 if(selected_branch != ''){
265 window.location = url;
265 window.location = url;
266 }else{
266 }else{
267 window.location = url_main;
267 window.location = url_main;
268 }
268 }
269
269
270 });
270 });
271
271
272 function set_canvas(width) {
272 function set_canvas(width) {
273 var c = document.getElementById('graph_nodes');
273 var c = document.getElementById('graph_nodes');
274 var t = document.getElementById('graph_content');
274 var t = document.getElementById('graph_content');
275 canvas = document.getElementById('graph_canvas');
275 canvas = document.getElementById('graph_canvas');
276 var div_h = t.clientHeight;
276 var div_h = t.clientHeight;
277 c.style.height=div_h+'px';
277 c.style.height=div_h+'px';
278 canvas.setAttribute('height',div_h);
278 canvas.setAttribute('height',div_h);
279 c.style.height=width+'px';
279 c.style.height=width+'px';
280 canvas.setAttribute('width',width);
280 canvas.setAttribute('width',width);
281 };
281 };
282 var heads = 1;
282 var heads = 1;
283 var line_count = 0;
283 var line_count = 0;
284 var jsdata = ${c.jsdata|n};
284 var jsdata = ${c.jsdata|n};
285
285
286 for (var i=0;i<jsdata.length;i++) {
286 for (var i=0;i<jsdata.length;i++) {
287 var in_l = jsdata[i][2];
287 var in_l = jsdata[i][2];
288 for (var j in in_l) {
288 for (var j in in_l) {
289 var m = in_l[j][1];
289 var m = in_l[j][1];
290 if (m > line_count)
290 if (m > line_count)
291 line_count = m;
291 line_count = m;
292 }
292 }
293 }
293 }
294 set_canvas(100);
294 set_canvas(100);
295
295
296 var r = new BranchRenderer();
296 var r = new BranchRenderer();
297 r.render(jsdata,100,line_count);
297 r.render(jsdata,100,line_count);
298
298
299 });
299 });
300 </script>
300 </script>
301 %else:
301 %else:
302 ${_('There are no changes yet')}
302 ${_('There are no changes yet')}
303 %endif
303 %endif
304 </div>
304 </div>
305 </div>
305 </div>
306 </%def>
306 </%def>
@@ -1,43 +1,43 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2
2
3 % if c.forks_pager:
3 % if c.forks_pager:
4 % for f in c.forks_pager:
4 % for f in c.forks_pager:
5 <div>
5 <div>
6 <div class="fork_user">
6 <div class="fork_user">
7 <div class="gravatar">
7 <div class="gravatar">
8 <img alt="gravatar" src="${h.gravatar_url(f.user.email,24)}"/>
8 <img alt="gravatar" src="${h.gravatar_url(f.user.email,24)}"/>
9 </div>
9 </div>
10 <span style="font-size: 20px">
10 <span style="font-size: 20px">
11 <b>${f.user.username}</b> (${f.user.name} ${f.user.lastname}) /
11 <b>${f.user.username}</b> (${f.user.name} ${f.user.lastname}) /
12 ${h.link_to(f.repo_name,h.url('summary_home',repo_name=f.repo_name))}
12 ${h.link_to(f.repo_name,h.url('summary_home',repo_name=f.repo_name))}
13 </span>
13 </span>
14 <div style="padding:5px 3px 3px 42px;">${f.description}</div>
14 <div style="padding:5px 3px 3px 42px;">${f.description}</div>
15 </div>
15 </div>
16 <div style="clear:both;padding-top: 10px"></div>
16 <div style="clear:both;padding-top: 10px"></div>
17 <div class="follower_date">${_('forked')} -
17 <div class="follower_date">${_('forked')} -
18 <span class="tooltip" title="${h.tooltip(h.fmt_date(f.created_on))}"> ${h.age(f.created_on)}</span>
18 <span class="tooltip" title="${h.tooltip(h.fmt_date(f.created_on))}"> ${h.age(f.created_on)}</span>
19 <a title="${_('compare fork with %s' % c.repo_name)}"
19 <a title="${_('compare fork with %s' % c.repo_name)}"
20 href="${h.url('compare_url',repo_name=f.repo_name,org_ref_type='branch',org_ref='default',other_ref_type='branch',other_ref='default', repo=c.repo_name)}"
20 href="${h.url('compare_url',repo_name=f.repo_name,org_ref_type='branch',org_ref='default',other_repo=c.repo_name,other_ref_type='branch',other_ref='default')}"
21 class="ui-btn small">${_('Compare fork')}</a>
21 class="ui-btn small">${_('Compare fork')}</a>
22 </div>
22 </div>
23 <div style="border-bottom: 1px solid #DDD;margin:10px 0px 10px 0px"></div>
23 <div style="border-bottom: 1px solid #DDD;margin:10px 0px 10px 0px"></div>
24 </div>
24 </div>
25 % endfor
25 % endfor
26 <div class="pagination-wh pagination-left">
26 <div class="pagination-wh pagination-left">
27 <script type="text/javascript">
27 <script type="text/javascript">
28 YUE.onDOMReady(function(){
28 YUE.onDOMReady(function(){
29 YUE.delegate("forks","click",function(e, matchedEl, container){
29 YUE.delegate("forks","click",function(e, matchedEl, container){
30 ypjax(e.target.href,"forks",function(){
30 ypjax(e.target.href,"forks",function(){
31 show_more_event();
31 show_more_event();
32 tooltip_activate();
32 tooltip_activate();
33 show_changeset_tooltip();
33 show_changeset_tooltip();
34 });
34 });
35 YUE.preventDefault(e);
35 YUE.preventDefault(e);
36 },'.pager_link');
36 },'.pager_link');
37 });
37 });
38 </script>
38 </script>
39 ${c.forks_pager.pager('$link_previous ~2~ $link_next')}
39 ${c.forks_pager.pager('$link_previous ~2~ $link_next')}
40 </div>
40 </div>
41 % else:
41 % else:
42 ${_('There are no forks yet')}
42 ${_('There are no forks yet')}
43 % endif
43 % endif
@@ -1,204 +1,204 b''
1 <%inherit file="/base/base.html"/>
1 <%inherit file="/base/base.html"/>
2
2
3 <%def name="title()">
3 <%def name="title()">
4 ${c.repo_name} ${_('New pull request')}
4 ${c.repo_name} ${_('New pull request')}
5 </%def>
5 </%def>
6
6
7 <%def name="breadcrumbs_links()">
7 <%def name="breadcrumbs_links()">
8 ${h.link_to(_(u'Home'),h.url('/'))}
8 ${h.link_to(_(u'Home'),h.url('/'))}
9 &raquo;
9 &raquo;
10 ${h.link_to(c.repo_name,h.url('changelog_home',repo_name=c.repo_name))}
10 ${h.link_to(c.repo_name,h.url('changelog_home',repo_name=c.repo_name))}
11 &raquo;
11 &raquo;
12 ${_('New pull request')}
12 ${_('New pull request')}
13 </%def>
13 </%def>
14
14
15 <%def name="main()">
15 <%def name="main()">
16
16
17 <div class="box">
17 <div class="box">
18 <!-- box / title -->
18 <!-- box / title -->
19 <div class="title">
19 <div class="title">
20 ${self.breadcrumbs()}
20 ${self.breadcrumbs()}
21 </div>
21 </div>
22 ${h.form(url('pullrequest', repo_name=c.repo_name), method='post', id='pull_request_form')}
22 ${h.form(url('pullrequest', repo_name=c.repo_name), method='post', id='pull_request_form')}
23 <div style="float:left;padding:0px 30px 30px 30px">
23 <div style="float:left;padding:0px 30px 30px 30px">
24 <input type="hidden" name="rev_start" value="${request.GET.get('rev_start')}" />
24 <input type="hidden" name="rev_start" value="${request.GET.get('rev_start')}" />
25 <input type="hidden" name="rev_end" value="${request.GET.get('rev_end')}" />
25 <input type="hidden" name="rev_end" value="${request.GET.get('rev_end')}" />
26
26
27 ##ORG
27 ##ORG
28 <div style="float:left">
28 <div style="float:left">
29 <div class="fork_user">
29 <div class="fork_user">
30 <div class="gravatar">
30 <div class="gravatar">
31 <img alt="gravatar" src="${h.gravatar_url(c.rhodecode_db_repo.user.email,24)}"/>
31 <img alt="gravatar" src="${h.gravatar_url(c.rhodecode_db_repo.user.email,24)}"/>
32 </div>
32 </div>
33 <span style="font-size: 20px">
33 <span style="font-size: 20px">
34 ${h.select('org_repo','',c.org_repos,class_='refs')}:${h.select('org_ref','',c.org_refs,class_='refs')}
34 ${h.select('org_repo','',c.org_repos,class_='refs')}:${h.select('org_ref','',c.org_refs,class_='refs')}
35 </span>
35 </span>
36 <div style="padding:5px 3px 3px 42px;">${c.rhodecode_db_repo.description}</div>
36 <div style="padding:5px 3px 3px 42px;">${c.rhodecode_db_repo.description}</div>
37 </div>
37 </div>
38 <div style="clear:both;padding-top: 10px"></div>
38 <div style="clear:both;padding-top: 10px"></div>
39 </div>
39 </div>
40 <div style="float:left;font-size:24px;padding:0px 20px">
40 <div style="float:left;font-size:24px;padding:0px 20px">
41 <img height=32 width=32 src="${h.url('/images/arrow_right_64.png')}"/>
41 <img height=32 width=32 src="${h.url('/images/arrow_right_64.png')}"/>
42 </div>
42 </div>
43
43
44 ##OTHER, most Probably the PARENT OF THIS FORK
44 ##OTHER, most Probably the PARENT OF THIS FORK
45 <div style="float:left">
45 <div style="float:left">
46 <div class="fork_user">
46 <div class="fork_user">
47 <div class="gravatar">
47 <div class="gravatar">
48 <img id="other_repo_gravatar" alt="gravatar" src=""/>
48 <img id="other_repo_gravatar" alt="gravatar" src=""/>
49 </div>
49 </div>
50 <span style="font-size: 20px">
50 <span style="font-size: 20px">
51 ${h.select('other_repo',c.default_pull_request ,c.other_repos,class_='refs')}:${h.select('other_ref',c.default_pull_request_rev,c.default_revs,class_='refs')}
51 ${h.select('other_repo',c.default_pull_request ,c.other_repos,class_='refs')}:${h.select('other_ref',c.default_pull_request_rev,c.default_revs,class_='refs')}
52 </span>
52 </span>
53 <span style="padding:3px">
53 <span style="padding:3px">
54 <a id="refresh" href="#" class="tooltip" title="${h.tooltip(_('refresh overview'))}">
54 <a id="refresh" href="#" class="tooltip" title="${h.tooltip(_('refresh overview'))}">
55 <img style="margin:3px" class="icon" title="${_('Refresh')}" alt="${_('Refresh')}" src="${h.url('/images/icons/arrow_refresh.png')}"/>
55 <img style="margin:3px" class="icon" title="${_('Refresh')}" alt="${_('Refresh')}" src="${h.url('/images/icons/arrow_refresh.png')}"/>
56 </a>
56 </a>
57 </span>
57 </span>
58 <div id="other_repo_desc" style="padding:5px 3px 3px 42px;"></div>
58 <div id="other_repo_desc" style="padding:5px 3px 3px 42px;"></div>
59 </div>
59 </div>
60 <div style="clear:both;padding-top: 10px"></div>
60 <div style="clear:both;padding-top: 10px"></div>
61 </div>
61 </div>
62 <div style="clear:both;padding-top: 10px"></div>
62 <div style="clear:both;padding-top: 10px"></div>
63 ## overview pulled by ajax
63 ## overview pulled by ajax
64 <div style="float:left" id="pull_request_overview"></div>
64 <div style="float:left" id="pull_request_overview"></div>
65 <div style="float:left;clear:both;padding:10px 10px 10px 0px;display:none">
65 <div style="float:left;clear:both;padding:10px 10px 10px 0px;display:none">
66 <a id="pull_request_overview_url" href="#">${_('Detailed compare view')}</a>
66 <a id="pull_request_overview_url" href="#">${_('Detailed compare view')}</a>
67 </div>
67 </div>
68 </div>
68 </div>
69 <div style="float:left; border-left:1px dashed #eee">
69 <div style="float:left; border-left:1px dashed #eee">
70 <h4>${_('Pull request reviewers')}</h4>
70 <h4>${_('Pull request reviewers')}</h4>
71 <div id="reviewers" style="padding:0px 0px 0px 15px">
71 <div id="reviewers" style="padding:0px 0px 0px 15px">
72 ## members goes here !
72 ## members goes here !
73 <div class="group_members_wrap">
73 <div class="group_members_wrap">
74 <ul id="review_members" class="group_members">
74 <ul id="review_members" class="group_members">
75 %for member in c.review_members:
75 %for member in c.review_members:
76 <li id="reviewer_${member.user_id}">
76 <li id="reviewer_${member.user_id}">
77 <div class="reviewers_member">
77 <div class="reviewers_member">
78 <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(member.email,14)}"/> </div>
78 <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(member.email,14)}"/> </div>
79 <div style="float:left">${member.full_name} (${_('owner')})</div>
79 <div style="float:left">${member.full_name} (${_('owner')})</div>
80 <input type="hidden" value="${member.user_id}" name="review_members" />
80 <input type="hidden" value="${member.user_id}" name="review_members" />
81 <span class="delete_icon action_button" onclick="removeReviewer(${member.user_id})"></span>
81 <span class="delete_icon action_button" onclick="removeReviewer(${member.user_id})"></span>
82 </div>
82 </div>
83 </li>
83 </li>
84 %endfor
84 %endfor
85 </ul>
85 </ul>
86 </div>
86 </div>
87
87
88 <div class='ac'>
88 <div class='ac'>
89 <div class="reviewer_ac">
89 <div class="reviewer_ac">
90 ${h.text('user', class_='yui-ac-input')}
90 ${h.text('user', class_='yui-ac-input')}
91 <span class="help-block">${_('Add reviewer to this pull request.')}</span>
91 <span class="help-block">${_('Add reviewer to this pull request.')}</span>
92 <div id="reviewers_container"></div>
92 <div id="reviewers_container"></div>
93 </div>
93 </div>
94 </div>
94 </div>
95 </div>
95 </div>
96 </div>
96 </div>
97 <h3>${_('Create new pull request')}</h3>
97 <h3>${_('Create new pull request')}</h3>
98
98
99 <div class="form">
99 <div class="form">
100 <!-- fields -->
100 <!-- fields -->
101
101
102 <div class="fields">
102 <div class="fields">
103
103
104 <div class="field">
104 <div class="field">
105 <div class="label">
105 <div class="label">
106 <label for="pullrequest_title">${_('Title')}:</label>
106 <label for="pullrequest_title">${_('Title')}:</label>
107 </div>
107 </div>
108 <div class="input">
108 <div class="input">
109 ${h.text('pullrequest_title',size=30)}
109 ${h.text('pullrequest_title',size=30)}
110 </div>
110 </div>
111 </div>
111 </div>
112
112
113 <div class="field">
113 <div class="field">
114 <div class="label label-textarea">
114 <div class="label label-textarea">
115 <label for="pullrequest_desc">${_('description')}:</label>
115 <label for="pullrequest_desc">${_('description')}:</label>
116 </div>
116 </div>
117 <div class="textarea text-area editor">
117 <div class="textarea text-area editor">
118 ${h.textarea('pullrequest_desc',size=30)}
118 ${h.textarea('pullrequest_desc',size=30)}
119 </div>
119 </div>
120 </div>
120 </div>
121
121
122 <div class="buttons">
122 <div class="buttons">
123 ${h.submit('save',_('Send pull request'),class_="ui-btn large")}
123 ${h.submit('save',_('Send pull request'),class_="ui-btn large")}
124 ${h.reset('reset',_('Reset'),class_="ui-btn large")}
124 ${h.reset('reset',_('Reset'),class_="ui-btn large")}
125 </div>
125 </div>
126 </div>
126 </div>
127 </div>
127 </div>
128 ${h.end_form()}
128 ${h.end_form()}
129
129
130 </div>
130 </div>
131
131
132 <script type="text/javascript">
132 <script type="text/javascript">
133 var _USERS_AC_DATA = ${c.users_array|n};
133 var _USERS_AC_DATA = ${c.users_array|n};
134 var _GROUPS_AC_DATA = ${c.users_groups_array|n};
134 var _GROUPS_AC_DATA = ${c.users_groups_array|n};
135 PullRequestAutoComplete('user', 'reviewers_container', _USERS_AC_DATA, _GROUPS_AC_DATA);
135 PullRequestAutoComplete('user', 'reviewers_container', _USERS_AC_DATA, _GROUPS_AC_DATA);
136
136
137 var other_repos_info = ${c.other_repos_info|n};
137 var other_repos_info = ${c.other_repos_info|n};
138
138
139 var loadPreview = function(){
139 var loadPreview = function(){
140 YUD.setStyle(YUD.get('pull_request_overview_url').parentElement,'display','none');
140 YUD.setStyle(YUD.get('pull_request_overview_url').parentElement,'display','none');
141 var url = "${h.url('compare_url',
141 var url = "${h.url('compare_url',
142 repo_name='org_repo',
142 repo_name='org_repo',
143 org_ref_type='org_ref_type', org_ref='org_ref',
143 org_ref_type='org_ref_type', org_ref='org_ref',
144 other_repo='other_repo',
144 other_ref_type='other_ref_type', other_ref='other_ref',
145 other_ref_type='other_ref_type', other_ref='other_ref',
145 repo='other_repo',
146 as_form=True,
146 as_form=True,
147 rev_start=request.GET.get('rev_start',''),
147 rev_start=request.GET.get('rev_start',''),
148 rev_end=request.GET.get('rev_end',''))}";
148 rev_end=request.GET.get('rev_end',''))}";
149
149
150 var select_refs = YUQ('#pull_request_form select.refs')
150 var select_refs = YUQ('#pull_request_form select.refs')
151 var rev_data = {}; // gather the org/other ref and repo here
151 var rev_data = {}; // gather the org/other ref and repo here
152 for(var i=0;i<select_refs.length;i++){
152 for(var i=0;i<select_refs.length;i++){
153 var select_ref = select_refs[i];
153 var select_ref = select_refs[i];
154 var select_ref_data = select_ref.value.split(':');
154 var select_ref_data = select_ref.value.split(':');
155 var key = null;
155 var key = null;
156 var val = null;
156 var val = null;
157
157
158 if(select_ref_data.length>1){
158 if(select_ref_data.length>1){
159 key = select_ref.name+"_type";
159 key = select_ref.name+"_type";
160 val = select_ref_data[0];
160 val = select_ref_data[0];
161 url = url.replace(key,val);
161 url = url.replace(key,val);
162 rev_data[key] = val;
162 rev_data[key] = val;
163
163
164 key = select_ref.name;
164 key = select_ref.name;
165 val = select_ref_data[1];
165 val = select_ref_data[1];
166 url = url.replace(key,val);
166 url = url.replace(key,val);
167 rev_data[key] = val;
167 rev_data[key] = val;
168
168
169 }else{
169 }else{
170 key = select_ref.name;
170 key = select_ref.name;
171 val = select_ref.value;
171 val = select_ref.value;
172 url = url.replace(key,val);
172 url = url.replace(key,val);
173 rev_data[key] = val;
173 rev_data[key] = val;
174 }
174 }
175 }
175 }
176
176
177 YUE.on('other_repo', 'change', function(e){
177 YUE.on('other_repo', 'change', function(e){
178 var repo_name = e.currentTarget.value;
178 var repo_name = e.currentTarget.value;
179 // replace the <select> of changed repo
179 // replace the <select> of changed repo
180 YUD.get('other_ref').innerHTML = other_repos_info[repo_name]['revs'];
180 YUD.get('other_ref').innerHTML = other_repos_info[repo_name]['revs'];
181 });
181 });
182
182
183 ypjax(url,'pull_request_overview', function(data){
183 ypjax(url,'pull_request_overview', function(data){
184 var sel_box = YUQ('#pull_request_form #other_repo')[0];
184 var sel_box = YUQ('#pull_request_form #other_repo')[0];
185 var repo_name = sel_box.options[sel_box.selectedIndex].value;
185 var repo_name = sel_box.options[sel_box.selectedIndex].value;
186 YUD.get('pull_request_overview_url').href = url;
186 YUD.get('pull_request_overview_url').href = url;
187 YUD.setStyle(YUD.get('pull_request_overview_url').parentElement,'display','');
187 YUD.setStyle(YUD.get('pull_request_overview_url').parentElement,'display','');
188 YUD.get('other_repo_gravatar').src = other_repos_info[repo_name]['gravatar'];
188 YUD.get('other_repo_gravatar').src = other_repos_info[repo_name]['gravatar'];
189 YUD.get('other_repo_desc').innerHTML = other_repos_info[repo_name]['description'];
189 YUD.get('other_repo_desc').innerHTML = other_repos_info[repo_name]['description'];
190 YUD.get('other_ref').innerHTML = other_repos_info[repo_name]['revs'];
190 YUD.get('other_ref').innerHTML = other_repos_info[repo_name]['revs'];
191 // select back the revision that was just compared
191 // select back the revision that was just compared
192 setSelectValue(YUD.get('other_ref'), rev_data['other_ref']);
192 setSelectValue(YUD.get('other_ref'), rev_data['other_ref']);
193 })
193 })
194 }
194 }
195 YUE.on('refresh','click',function(e){
195 YUE.on('refresh','click',function(e){
196 loadPreview()
196 loadPreview()
197 })
197 })
198
198
199 //lazy load overview after 0.5s
199 //lazy load overview after 0.5s
200 setTimeout(loadPreview, 500)
200 setTimeout(loadPreview, 500)
201
201
202 </script>
202 </script>
203
203
204 </%def>
204 </%def>
@@ -1,347 +1,347 b''
1 from rhodecode.tests import *
1 from rhodecode.tests import *
2 from rhodecode.model.repo import RepoModel
2 from rhodecode.model.repo import RepoModel
3 from rhodecode.model.meta import Session
3 from rhodecode.model.meta import Session
4 from rhodecode.model.db import Repository
4 from rhodecode.model.db import Repository
5 from rhodecode.model.scm import ScmModel
5 from rhodecode.model.scm import ScmModel
6 from rhodecode.lib.vcs.backends.base import EmptyChangeset
6 from rhodecode.lib.vcs.backends.base import EmptyChangeset
7
7
8
8
9 def _fork_repo(fork_name, vcs_type, parent=None):
9 def _fork_repo(fork_name, vcs_type, parent=None):
10 if vcs_type =='hg':
10 if vcs_type =='hg':
11 _REPO = HG_REPO
11 _REPO = HG_REPO
12 elif vcs_type == 'git':
12 elif vcs_type == 'git':
13 _REPO = GIT_REPO
13 _REPO = GIT_REPO
14
14
15 if parent:
15 if parent:
16 _REPO = parent
16 _REPO = parent
17
17
18 form_data = dict(
18 form_data = dict(
19 repo_name=fork_name,
19 repo_name=fork_name,
20 repo_name_full=fork_name,
20 repo_name_full=fork_name,
21 repo_group=None,
21 repo_group=None,
22 repo_type=vcs_type,
22 repo_type=vcs_type,
23 description='',
23 description='',
24 private=False,
24 private=False,
25 copy_permissions=False,
25 copy_permissions=False,
26 landing_rev='tip',
26 landing_rev='tip',
27 update_after_clone=False,
27 update_after_clone=False,
28 fork_parent_id=Repository.get_by_repo_name(_REPO),
28 fork_parent_id=Repository.get_by_repo_name(_REPO),
29 )
29 )
30 repo = RepoModel().create_fork(form_data, cur_user=TEST_USER_ADMIN_LOGIN)
30 repo = RepoModel().create_fork(form_data, cur_user=TEST_USER_ADMIN_LOGIN)
31
31
32 Session().commit()
32 Session().commit()
33 return Repository.get_by_repo_name(fork_name)
33 return Repository.get_by_repo_name(fork_name)
34
34
35
35
36 def _commit_change(repo, filename, content, message, vcs_type, parent=None, newfile=False):
36 def _commit_change(repo, filename, content, message, vcs_type, parent=None, newfile=False):
37 repo = Repository.get_by_repo_name(repo)
37 repo = Repository.get_by_repo_name(repo)
38 _cs = parent
38 _cs = parent
39 if not parent:
39 if not parent:
40 _cs = EmptyChangeset(alias=vcs_type)
40 _cs = EmptyChangeset(alias=vcs_type)
41
41
42 if newfile:
42 if newfile:
43 cs = ScmModel().create_node(
43 cs = ScmModel().create_node(
44 repo=repo.scm_instance, repo_name=repo.repo_name,
44 repo=repo.scm_instance, repo_name=repo.repo_name,
45 cs=_cs, user=TEST_USER_ADMIN_LOGIN,
45 cs=_cs, user=TEST_USER_ADMIN_LOGIN,
46 author=TEST_USER_ADMIN_LOGIN,
46 author=TEST_USER_ADMIN_LOGIN,
47 message=message,
47 message=message,
48 content=content,
48 content=content,
49 f_path=filename
49 f_path=filename
50 )
50 )
51 else:
51 else:
52 cs = ScmModel().commit_change(
52 cs = ScmModel().commit_change(
53 repo=repo.scm_instance, repo_name=repo.repo_name,
53 repo=repo.scm_instance, repo_name=repo.repo_name,
54 cs=parent, user=TEST_USER_ADMIN_LOGIN,
54 cs=parent, user=TEST_USER_ADMIN_LOGIN,
55 author=TEST_USER_ADMIN_LOGIN,
55 author=TEST_USER_ADMIN_LOGIN,
56 message=message,
56 message=message,
57 content=content,
57 content=content,
58 f_path=filename
58 f_path=filename
59 )
59 )
60 return cs
60 return cs
61
61
62
62
63 class TestCompareController(TestController):
63 class TestCompareController(TestController):
64
64
65 def test_compare_forks_on_branch_extra_commits_hg(self):
65 def test_compare_forks_on_branch_extra_commits_hg(self):
66 self.log_user()
66 self.log_user()
67
67
68 repo1 = RepoModel().create_repo(repo_name='one', repo_type='hg',
68 repo1 = RepoModel().create_repo(repo_name='one', repo_type='hg',
69 description='diff-test',
69 description='diff-test',
70 owner=TEST_USER_ADMIN_LOGIN)
70 owner=TEST_USER_ADMIN_LOGIN)
71 r1_id = repo1.repo_id
71 r1_id = repo1.repo_id
72 Session().commit()
72 Session().commit()
73 #commit something !
73 #commit something !
74 cs0 = _commit_change(repo1.repo_name, filename='file1', content='line1\n',
74 cs0 = _commit_change(repo1.repo_name, filename='file1', content='line1\n',
75 message='commit1', vcs_type='hg', parent=None, newfile=True)
75 message='commit1', vcs_type='hg', parent=None, newfile=True)
76
76
77 #fork this repo
77 #fork this repo
78 repo2 = _fork_repo('one-fork', 'hg', parent='one')
78 repo2 = _fork_repo('one-fork', 'hg', parent='one')
79 Session().commit()
79 Session().commit()
80 r2_id = repo2.repo_id
80 r2_id = repo2.repo_id
81
81
82 #add two extra commit into fork
82 #add two extra commit into fork
83 cs1 = _commit_change(repo2.repo_name, filename='file1', content='line1\nline2\n',
83 cs1 = _commit_change(repo2.repo_name, filename='file1', content='line1\nline2\n',
84 message='commit2', vcs_type='hg', parent=cs0)
84 message='commit2', vcs_type='hg', parent=cs0)
85
85
86 cs2 = _commit_change(repo2.repo_name, filename='file1', content='line1\nline2\nline3\n',
86 cs2 = _commit_change(repo2.repo_name, filename='file1', content='line1\nline2\nline3\n',
87 message='commit3', vcs_type='hg', parent=cs1)
87 message='commit3', vcs_type='hg', parent=cs1)
88
88
89 rev1 = 'default'
89 rev1 = 'default'
90 rev2 = 'default'
90 rev2 = 'default'
91 response = self.app.get(url(controller='compare', action='index',
91 response = self.app.get(url(controller='compare', action='index',
92 repo_name=repo2.repo_name,
92 repo_name=repo2.repo_name,
93 org_ref_type="branch",
93 org_ref_type="branch",
94 org_ref=rev1,
94 org_ref=rev1,
95 other_repo=repo1.repo_name,
95 other_ref_type="branch",
96 other_ref_type="branch",
96 other_ref=rev2,
97 other_ref=rev2,
97 repo=repo1.repo_name
98 ))
98 ))
99
99
100 try:
100 try:
101 response.mustcontain('%s@%s -&gt; %s@%s' % (repo2.repo_name, rev1, repo1.repo_name, rev2))
101 response.mustcontain('%s@%s -&gt; %s@%s' % (repo2.repo_name, rev1, repo1.repo_name, rev2))
102 response.mustcontain("""Showing 2 commits""")
102 response.mustcontain("""Showing 2 commits""")
103 response.mustcontain("""1 file changed with 2 insertions and 0 deletions""")
103 response.mustcontain("""1 file changed with 2 insertions and 0 deletions""")
104
104
105 response.mustcontain("""<div class="message tooltip" title="commit2" style="white-space:normal">commit2</div>""")
105 response.mustcontain("""<div class="message tooltip" title="commit2" style="white-space:normal">commit2</div>""")
106 response.mustcontain("""<div class="message tooltip" title="commit3" style="white-space:normal">commit3</div>""")
106 response.mustcontain("""<div class="message tooltip" title="commit3" style="white-space:normal">commit3</div>""")
107
107
108 response.mustcontain("""<a href="/%s/changeset/%s">r1:%s</a>""" % (repo2.repo_name, cs1.raw_id, cs1.short_id))
108 response.mustcontain("""<a href="/%s/changeset/%s">r1:%s</a>""" % (repo2.repo_name, cs1.raw_id, cs1.short_id))
109 response.mustcontain("""<a href="/%s/changeset/%s">r2:%s</a>""" % (repo2.repo_name, cs2.raw_id, cs2.short_id))
109 response.mustcontain("""<a href="/%s/changeset/%s">r2:%s</a>""" % (repo2.repo_name, cs2.raw_id, cs2.short_id))
110 ## files
110 ## files
111 response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s#C--826e8142e6ba">file1</a>""" % (repo2.repo_name, rev1, rev2))
111 response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s#C--826e8142e6ba">file1</a>""" % (repo2.repo_name, rev1, rev2))
112
112
113 finally:
113 finally:
114 RepoModel().delete(r2_id)
114 RepoModel().delete(r2_id)
115 RepoModel().delete(r1_id)
115 RepoModel().delete(r1_id)
116
116
117
117
118 def test_compare_forks_on_branch_extra_commits_origin_has_incomming_hg(self):
118 def test_compare_forks_on_branch_extra_commits_origin_has_incomming_hg(self):
119 self.log_user()
119 self.log_user()
120
120
121 repo1 = RepoModel().create_repo(repo_name='one', repo_type='hg',
121 repo1 = RepoModel().create_repo(repo_name='one', repo_type='hg',
122 description='diff-test',
122 description='diff-test',
123 owner=TEST_USER_ADMIN_LOGIN)
123 owner=TEST_USER_ADMIN_LOGIN)
124 r1_id = repo1.repo_id
124 r1_id = repo1.repo_id
125 Session().commit()
125 Session().commit()
126 #commit something !
126 #commit something !
127 cs0 = _commit_change(repo1.repo_name, filename='file1', content='line1\n',
127 cs0 = _commit_change(repo1.repo_name, filename='file1', content='line1\n',
128 message='commit1', vcs_type='hg', parent=None, newfile=True)
128 message='commit1', vcs_type='hg', parent=None, newfile=True)
129
129
130 #fork this repo
130 #fork this repo
131 repo2 = _fork_repo('one-fork', 'hg', parent='one')
131 repo2 = _fork_repo('one-fork', 'hg', parent='one')
132 Session().commit()
132 Session().commit()
133
133
134 #now commit something to origin repo
134 #now commit something to origin repo
135 cs1_prim = _commit_change(repo1.repo_name, filename='file2', content='line1file2\n',
135 cs1_prim = _commit_change(repo1.repo_name, filename='file2', content='line1file2\n',
136 message='commit2', vcs_type='hg', parent=cs0, newfile=True)
136 message='commit2', vcs_type='hg', parent=cs0, newfile=True)
137
137
138 r2_id = repo2.repo_id
138 r2_id = repo2.repo_id
139
139
140 #add two extra commit into fork
140 #add two extra commit into fork
141 cs1 = _commit_change(repo2.repo_name, filename='file1', content='line1\nline2\n',
141 cs1 = _commit_change(repo2.repo_name, filename='file1', content='line1\nline2\n',
142 message='commit2', vcs_type='hg', parent=cs0)
142 message='commit2', vcs_type='hg', parent=cs0)
143
143
144 cs2 = _commit_change(repo2.repo_name, filename='file1', content='line1\nline2\nline3\n',
144 cs2 = _commit_change(repo2.repo_name, filename='file1', content='line1\nline2\nline3\n',
145 message='commit3', vcs_type='hg', parent=cs1)
145 message='commit3', vcs_type='hg', parent=cs1)
146
146
147 rev1 = 'default'
147 rev1 = 'default'
148 rev2 = 'default'
148 rev2 = 'default'
149 response = self.app.get(url(controller='compare', action='index',
149 response = self.app.get(url(controller='compare', action='index',
150 repo_name=repo2.repo_name,
150 repo_name=repo2.repo_name,
151 org_ref_type="branch",
151 org_ref_type="branch",
152 org_ref=rev1,
152 org_ref=rev1,
153 other_repo=repo1.repo_name,
153 other_ref_type="branch",
154 other_ref_type="branch",
154 other_ref=rev2,
155 other_ref=rev2,
155 repo=repo1.repo_name
156 ))
156 ))
157
157
158 try:
158 try:
159 response.mustcontain('%s@%s -&gt; %s@%s' % (repo2.repo_name, rev1, repo1.repo_name, rev2))
159 response.mustcontain('%s@%s -&gt; %s@%s' % (repo2.repo_name, rev1, repo1.repo_name, rev2))
160 response.mustcontain("""Showing 2 commits""")
160 response.mustcontain("""Showing 2 commits""")
161 response.mustcontain("""1 file changed with 2 insertions and 0 deletions""")
161 response.mustcontain("""1 file changed with 2 insertions and 0 deletions""")
162
162
163 response.mustcontain("""<div class="message tooltip" title="commit2" style="white-space:normal">commit2</div>""")
163 response.mustcontain("""<div class="message tooltip" title="commit2" style="white-space:normal">commit2</div>""")
164 response.mustcontain("""<div class="message tooltip" title="commit3" style="white-space:normal">commit3</div>""")
164 response.mustcontain("""<div class="message tooltip" title="commit3" style="white-space:normal">commit3</div>""")
165
165
166 response.mustcontain("""<a href="/%s/changeset/%s">r1:%s</a>""" % (repo2.repo_name, cs1.raw_id, cs1.short_id))
166 response.mustcontain("""<a href="/%s/changeset/%s">r1:%s</a>""" % (repo2.repo_name, cs1.raw_id, cs1.short_id))
167 response.mustcontain("""<a href="/%s/changeset/%s">r2:%s</a>""" % (repo2.repo_name, cs2.raw_id, cs2.short_id))
167 response.mustcontain("""<a href="/%s/changeset/%s">r2:%s</a>""" % (repo2.repo_name, cs2.raw_id, cs2.short_id))
168 ## files
168 ## files
169 response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s#C--826e8142e6ba">file1</a>""" % (repo2.repo_name, rev1, rev2))
169 response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s#C--826e8142e6ba">file1</a>""" % (repo2.repo_name, rev1, rev2))
170
170
171 finally:
171 finally:
172 RepoModel().delete(r2_id)
172 RepoModel().delete(r2_id)
173 RepoModel().delete(r1_id)
173 RepoModel().delete(r1_id)
174
174
175
175
176 # def test_compare_remote_repos_remote_flag_off(self):
176 # def test_compare_remote_repos_remote_flag_off(self):
177 # self.log_user()
177 # self.log_user()
178 # _fork_repo(HG_FORK, 'hg')
178 # _fork_repo(HG_FORK, 'hg')
179 #
179 #
180 # rev1 = '56349e29c2af'
180 # rev1 = '56349e29c2af'
181 # rev2 = '7d4bc8ec6be5'
181 # rev2 = '7d4bc8ec6be5'
182 #
182 #
183 # response = self.app.get(url(controller='compare', action='index',
183 # response = self.app.get(url(controller='compare', action='index',
184 # repo_name=HG_REPO,
184 # repo_name=HG_REPO,
185 # org_ref_type="rev",
185 # org_ref_type="rev",
186 # org_ref=rev1,
186 # org_ref=rev1,
187 # other_ref_type="rev",
187 # other_ref_type="rev",
188 # other_ref=rev2,
188 # other_ref=rev2,
189 # repo=HG_FORK,
189 # repo=HG_FORK,
190 # bundle=False,
190 # bundle=False,
191 # ))
191 # ))
192 #
192 #
193 # try:
193 # try:
194 # response.mustcontain('%s@%s -&gt; %s@%s' % (HG_REPO, rev1, HG_FORK, rev2))
194 # response.mustcontain('%s@%s -&gt; %s@%s' % (HG_REPO, rev1, HG_FORK, rev2))
195 # ## outgoing changesets between those revisions
195 # ## outgoing changesets between those revisions
196 #
196 #
197 # response.mustcontain("""<a href="/%s/changeset/2dda4e345facb0ccff1a191052dd1606dba6781d">r4:2dda4e345fac</a>""" % (HG_REPO))
197 # response.mustcontain("""<a href="/%s/changeset/2dda4e345facb0ccff1a191052dd1606dba6781d">r4:2dda4e345fac</a>""" % (HG_REPO))
198 # response.mustcontain("""<a href="/%s/changeset/6fff84722075f1607a30f436523403845f84cd9e">r5:6fff84722075</a>""" % (HG_REPO))
198 # response.mustcontain("""<a href="/%s/changeset/6fff84722075f1607a30f436523403845f84cd9e">r5:6fff84722075</a>""" % (HG_REPO))
199 # response.mustcontain("""<a href="/%s/changeset/7d4bc8ec6be56c0f10425afb40b6fc315a4c25e7">r6:%s</a>""" % (HG_REPO, rev2))
199 # response.mustcontain("""<a href="/%s/changeset/7d4bc8ec6be56c0f10425afb40b6fc315a4c25e7">r6:%s</a>""" % (HG_REPO, rev2))
200 #
200 #
201 # ## files
201 # ## files
202 # response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--9c390eb52cd6">vcs/backends/hg.py</a>""" % (HG_REPO, rev1, rev2))
202 # response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--9c390eb52cd6">vcs/backends/hg.py</a>""" % (HG_REPO, rev1, rev2))
203 # response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--41b41c1f2796">vcs/backends/__init__.py</a>""" % (HG_REPO, rev1, rev2))
203 # response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--41b41c1f2796">vcs/backends/__init__.py</a>""" % (HG_REPO, rev1, rev2))
204 # response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--2f574d260608">vcs/backends/base.py</a>""" % (HG_REPO, rev1, rev2))
204 # response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--2f574d260608">vcs/backends/base.py</a>""" % (HG_REPO, rev1, rev2))
205 # finally:
205 # finally:
206 # RepoModel().delete(HG_FORK)
206 # RepoModel().delete(HG_FORK)
207
207
208
208
209
209
210 #
210 #
211 # def test_compare_remote_branches_hg(self):
211 # def test_compare_remote_branches_hg(self):
212 # self.log_user()
212 # self.log_user()
213 #
213 #
214 # _fork_repo(HG_FORK, 'hg')
214 # _fork_repo(HG_FORK, 'hg')
215 #
215 #
216 # rev1 = '56349e29c2af'
216 # rev1 = '56349e29c2af'
217 # rev2 = '7d4bc8ec6be5'
217 # rev2 = '7d4bc8ec6be5'
218 #
218 #
219 # response = self.app.get(url(controller='compare', action='index',
219 # response = self.app.get(url(controller='compare', action='index',
220 # repo_name=HG_REPO,
220 # repo_name=HG_REPO,
221 # org_ref_type="rev",
221 # org_ref_type="rev",
222 # org_ref=rev1,
222 # org_ref=rev1,
223 # other_ref_type="rev",
223 # other_ref_type="rev",
224 # other_ref=rev2,
224 # other_ref=rev2,
225 # repo=HG_FORK,
225 # repo=HG_FORK,
226 # ))
226 # ))
227 #
227 #
228 # try:
228 # try:
229 # response.mustcontain('%s@%s -&gt; %s@%s' % (HG_REPO, rev1, HG_FORK, rev2))
229 # response.mustcontain('%s@%s -&gt; %s@%s' % (HG_REPO, rev1, HG_FORK, rev2))
230 # ## outgoing changesets between those revisions
230 # ## outgoing changesets between those revisions
231 #
231 #
232 # response.mustcontain("""<a href="/%s/changeset/2dda4e345facb0ccff1a191052dd1606dba6781d">r4:2dda4e345fac</a>""" % (HG_REPO))
232 # response.mustcontain("""<a href="/%s/changeset/2dda4e345facb0ccff1a191052dd1606dba6781d">r4:2dda4e345fac</a>""" % (HG_REPO))
233 # response.mustcontain("""<a href="/%s/changeset/6fff84722075f1607a30f436523403845f84cd9e">r5:6fff84722075</a>""" % (HG_REPO))
233 # response.mustcontain("""<a href="/%s/changeset/6fff84722075f1607a30f436523403845f84cd9e">r5:6fff84722075</a>""" % (HG_REPO))
234 # response.mustcontain("""<a href="/%s/changeset/7d4bc8ec6be56c0f10425afb40b6fc315a4c25e7">r6:%s</a>""" % (HG_REPO, rev2))
234 # response.mustcontain("""<a href="/%s/changeset/7d4bc8ec6be56c0f10425afb40b6fc315a4c25e7">r6:%s</a>""" % (HG_REPO, rev2))
235 #
235 #
236 # ## files
236 # ## files
237 # response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--9c390eb52cd6">vcs/backends/hg.py</a>""" % (HG_REPO, rev1, rev2))
237 # response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--9c390eb52cd6">vcs/backends/hg.py</a>""" % (HG_REPO, rev1, rev2))
238 # response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--41b41c1f2796">vcs/backends/__init__.py</a>""" % (HG_REPO, rev1, rev2))
238 # response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--41b41c1f2796">vcs/backends/__init__.py</a>""" % (HG_REPO, rev1, rev2))
239 # response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--2f574d260608">vcs/backends/base.py</a>""" % (HG_REPO, rev1, rev2))
239 # response.mustcontain("""<a href="/%s/compare/rev@%s...rev@%s#C--2f574d260608">vcs/backends/base.py</a>""" % (HG_REPO, rev1, rev2))
240 # finally:
240 # finally:
241 # RepoModel().delete(HG_FORK)
241 # RepoModel().delete(HG_FORK)
242 #
242 #
243 # def test_org_repo_new_commits_after_forking_simple_diff(self):
243 # def test_org_repo_new_commits_after_forking_simple_diff(self):
244 # self.log_user()
244 # self.log_user()
245 #
245 #
246 # repo1 = RepoModel().create_repo(repo_name='one', repo_type='hg',
246 # repo1 = RepoModel().create_repo(repo_name='one', repo_type='hg',
247 # description='diff-test',
247 # description='diff-test',
248 # owner=TEST_USER_ADMIN_LOGIN)
248 # owner=TEST_USER_ADMIN_LOGIN)
249 #
249 #
250 # Session().commit()
250 # Session().commit()
251 # r1_id = repo1.repo_id
251 # r1_id = repo1.repo_id
252 # r1_name = repo1.repo_name
252 # r1_name = repo1.repo_name
253 #
253 #
254 # #commit something initially !
254 # #commit something initially !
255 # cs0 = ScmModel().create_node(
255 # cs0 = ScmModel().create_node(
256 # repo=repo1.scm_instance, repo_name=r1_name,
256 # repo=repo1.scm_instance, repo_name=r1_name,
257 # cs=EmptyChangeset(alias='hg'), user=TEST_USER_ADMIN_LOGIN,
257 # cs=EmptyChangeset(alias='hg'), user=TEST_USER_ADMIN_LOGIN,
258 # author=TEST_USER_ADMIN_LOGIN,
258 # author=TEST_USER_ADMIN_LOGIN,
259 # message='commit1',
259 # message='commit1',
260 # content='line1',
260 # content='line1',
261 # f_path='file1'
261 # f_path='file1'
262 # )
262 # )
263 # Session().commit()
263 # Session().commit()
264 # self.assertEqual(repo1.scm_instance.revisions, [cs0.raw_id])
264 # self.assertEqual(repo1.scm_instance.revisions, [cs0.raw_id])
265 # #fork the repo1
265 # #fork the repo1
266 # repo2 = RepoModel().create_repo(repo_name='one-fork', repo_type='hg',
266 # repo2 = RepoModel().create_repo(repo_name='one-fork', repo_type='hg',
267 # description='compare-test',
267 # description='compare-test',
268 # clone_uri=repo1.repo_full_path,
268 # clone_uri=repo1.repo_full_path,
269 # owner=TEST_USER_ADMIN_LOGIN, fork_of='one')
269 # owner=TEST_USER_ADMIN_LOGIN, fork_of='one')
270 # Session().commit()
270 # Session().commit()
271 # self.assertEqual(repo2.scm_instance.revisions, [cs0.raw_id])
271 # self.assertEqual(repo2.scm_instance.revisions, [cs0.raw_id])
272 # r2_id = repo2.repo_id
272 # r2_id = repo2.repo_id
273 # r2_name = repo2.repo_name
273 # r2_name = repo2.repo_name
274 #
274 #
275 # #make 3 new commits in fork
275 # #make 3 new commits in fork
276 # cs1 = ScmModel().create_node(
276 # cs1 = ScmModel().create_node(
277 # repo=repo2.scm_instance, repo_name=r2_name,
277 # repo=repo2.scm_instance, repo_name=r2_name,
278 # cs=repo2.scm_instance[-1], user=TEST_USER_ADMIN_LOGIN,
278 # cs=repo2.scm_instance[-1], user=TEST_USER_ADMIN_LOGIN,
279 # author=TEST_USER_ADMIN_LOGIN,
279 # author=TEST_USER_ADMIN_LOGIN,
280 # message='commit1-fork',
280 # message='commit1-fork',
281 # content='file1-line1-from-fork',
281 # content='file1-line1-from-fork',
282 # f_path='file1-fork'
282 # f_path='file1-fork'
283 # )
283 # )
284 # cs2 = ScmModel().create_node(
284 # cs2 = ScmModel().create_node(
285 # repo=repo2.scm_instance, repo_name=r2_name,
285 # repo=repo2.scm_instance, repo_name=r2_name,
286 # cs=cs1, user=TEST_USER_ADMIN_LOGIN,
286 # cs=cs1, user=TEST_USER_ADMIN_LOGIN,
287 # author=TEST_USER_ADMIN_LOGIN,
287 # author=TEST_USER_ADMIN_LOGIN,
288 # message='commit2-fork',
288 # message='commit2-fork',
289 # content='file2-line1-from-fork',
289 # content='file2-line1-from-fork',
290 # f_path='file2-fork'
290 # f_path='file2-fork'
291 # )
291 # )
292 # cs3 = ScmModel().create_node(
292 # cs3 = ScmModel().create_node(
293 # repo=repo2.scm_instance, repo_name=r2_name,
293 # repo=repo2.scm_instance, repo_name=r2_name,
294 # cs=cs2, user=TEST_USER_ADMIN_LOGIN,
294 # cs=cs2, user=TEST_USER_ADMIN_LOGIN,
295 # author=TEST_USER_ADMIN_LOGIN,
295 # author=TEST_USER_ADMIN_LOGIN,
296 # message='commit3-fork',
296 # message='commit3-fork',
297 # content='file3-line1-from-fork',
297 # content='file3-line1-from-fork',
298 # f_path='file3-fork'
298 # f_path='file3-fork'
299 # )
299 # )
300 #
300 #
301 # #compare !
301 # #compare !
302 # rev1 = 'default'
302 # rev1 = 'default'
303 # rev2 = 'default'
303 # rev2 = 'default'
304 # response = self.app.get(url(controller='compare', action='index',
304 # response = self.app.get(url(controller='compare', action='index',
305 # repo_name=r2_name,
305 # repo_name=r2_name,
306 # org_ref_type="branch",
306 # org_ref_type="branch",
307 # org_ref=rev1,
307 # org_ref=rev1,
308 # other_ref_type="branch",
308 # other_ref_type="branch",
309 # other_ref=rev2,
309 # other_ref=rev2,
310 # repo=r1_name,
310 # repo=r1_name,
311 # bundle=False,
311 # bundle=False,
312 # ))
312 # ))
313 #
313 #
314 # try:
314 # try:
315 # #response.mustcontain('%s@%s -&gt; %s@%s' % (r2_name, rev1, r1_name, rev2))
315 # #response.mustcontain('%s@%s -&gt; %s@%s' % (r2_name, rev1, r1_name, rev2))
316 #
316 #
317 # #add new commit into parent !
317 # #add new commit into parent !
318 # cs0 = ScmModel().create_node(
318 # cs0 = ScmModel().create_node(
319 # repo=repo1.scm_instance, repo_name=r1_name,
319 # repo=repo1.scm_instance, repo_name=r1_name,
320 # cs=EmptyChangeset(alias='hg'), user=TEST_USER_ADMIN_LOGIN,
320 # cs=EmptyChangeset(alias='hg'), user=TEST_USER_ADMIN_LOGIN,
321 # author=TEST_USER_ADMIN_LOGIN,
321 # author=TEST_USER_ADMIN_LOGIN,
322 # message='commit2',
322 # message='commit2',
323 # content='line1',
323 # content='line1',
324 # f_path='file2'
324 # f_path='file2'
325 # )
325 # )
326 # #compare !
326 # #compare !
327 # rev1 = 'default'
327 # rev1 = 'default'
328 # rev2 = 'default'
328 # rev2 = 'default'
329 # response = self.app.get(url(controller='compare', action='index',
329 # response = self.app.get(url(controller='compare', action='index',
330 # repo_name=r2_name,
330 # repo_name=r2_name,
331 # org_ref_type="branch",
331 # org_ref_type="branch",
332 # org_ref=rev1,
332 # org_ref=rev1,
333 # other_ref_type="branch",
333 # other_ref_type="branch",
334 # other_ref=rev2,
334 # other_ref=rev2,
335 # repo=r1_name,
335 # repo=r1_name,
336 # bundle=False
336 # bundle=False
337 # ))
337 # ))
338 #
338 #
339 # response.mustcontain('%s@%s -&gt; %s@%s' % (r2_name, rev1, r1_name, rev2))
339 # response.mustcontain('%s@%s -&gt; %s@%s' % (r2_name, rev1, r1_name, rev2))
340 # response.mustcontain("""file1-line1-from-fork""")
340 # response.mustcontain("""file1-line1-from-fork""")
341 # response.mustcontain("""file2-line1-from-fork""")
341 # response.mustcontain("""file2-line1-from-fork""")
342 # response.mustcontain("""file3-line1-from-fork""")
342 # response.mustcontain("""file3-line1-from-fork""")
343 # self.assertFalse("""<a href="#">file2</a>""" in response.body) # new commit from parent
343 # self.assertFalse("""<a href="#">file2</a>""" in response.body) # new commit from parent
344 # self.assertFalse("""line1-from-new-parent""" in response.body)
344 # self.assertFalse("""line1-from-new-parent""" in response.body)
345 # finally:
345 # finally:
346 # RepoModel().delete(r2_id)
346 # RepoModel().delete(r2_id)
347 # RepoModel().delete(r1_id)
347 # RepoModel().delete(r1_id)
General Comments 0
You need to be logged in to leave comments. Login now