Commit d906f19c5ba961f34dad995d65494c5fec7bd3f4
Exists in
spb-stable
and in
2 other branches
Merge branch 'move-protected-branches' into 'master'
Move protected branches to Project settings page Because all settings should be in one place
Showing
13 changed files
with
109 additions
and
119 deletions
Show diff stats
app/controllers/projects/branches_controller.rb
... | ... | @@ -7,7 +7,9 @@ class Projects::BranchesController < Projects::ApplicationController |
7 | 7 | before_filter :authorize_push!, only: [:create, :destroy] |
8 | 8 | |
9 | 9 | def index |
10 | - @branches = Kaminari.paginate_array(@repository.branches).page(params[:page]).per(30) | |
10 | + @sort = params[:sort] || 'name' | |
11 | + @branches = @repository.branches_sorted_by(@sort) | |
12 | + @branches = Kaminari.paginate_array(@branches).page(params[:page]).per(30) | |
11 | 13 | end |
12 | 14 | |
13 | 15 | def recent | ... | ... |
app/controllers/projects/protected_branches_controller.rb
1 | 1 | class Projects::ProtectedBranchesController < Projects::ApplicationController |
2 | 2 | # Authorize |
3 | - before_filter :authorize_read_project! | |
4 | 3 | before_filter :require_non_empty_project |
4 | + before_filter :authorize_admin_project! | |
5 | 5 | |
6 | - before_filter :authorize_admin_project!, only: [:destroy, :create] | |
6 | + layout "project_settings" | |
7 | 7 | |
8 | 8 | def index |
9 | 9 | @branches = @project.protected_branches.to_a | ... | ... |
app/helpers/tab_helper.rb
... | ... | @@ -75,7 +75,7 @@ module TabHelper |
75 | 75 | def project_tab_class |
76 | 76 | return "active" if current_page?(controller: "/projects", action: :edit, id: @project) |
77 | 77 | |
78 | - if ['services', 'hooks', 'deploy_keys', 'team_members'].include? controller.controller_name | |
78 | + if ['services', 'hooks', 'deploy_keys', 'team_members', 'protected_branches'].include? controller.controller_name | |
79 | 79 | "active" |
80 | 80 | end |
81 | 81 | end | ... | ... |
app/models/repository.rb
... | ... | @@ -55,12 +55,6 @@ class Repository |
55 | 55 | tags.find { |tag| tag.name == name } |
56 | 56 | end |
57 | 57 | |
58 | - def recent_branches(limit = 20) | |
59 | - branches.sort do |a, b| | |
60 | - commit(b.target).committed_date <=> commit(a.target).committed_date | |
61 | - end[0..limit] | |
62 | - end | |
63 | - | |
64 | 58 | def add_branch(branch_name, ref) |
65 | 59 | Rails.cache.delete(cache_key(:branch_names)) |
66 | 60 | |
... | ... | @@ -220,4 +214,19 @@ class Repository |
220 | 214 | def clean_old_archives |
221 | 215 | Gitlab::Popen.popen(%W(find #{Gitlab.config.gitlab.repository_downloads_path} -mmin +120 -delete)) |
222 | 216 | end |
217 | + | |
218 | + def branches_sorted_by(value) | |
219 | + case value | |
220 | + when 'recently_updated' | |
221 | + branches.sort do |a, b| | |
222 | + commit(b.target).committed_date <=> commit(a.target).committed_date | |
223 | + end | |
224 | + when 'last_updated' | |
225 | + branches.sort do |a, b| | |
226 | + commit(a.target).committed_date <=> commit(b.target).committed_date | |
227 | + end | |
228 | + else | |
229 | + branches | |
230 | + end | |
231 | + end | |
223 | 232 | end | ... | ... |
app/views/layouts/nav/_project.html.haml
... | ... | @@ -8,7 +8,7 @@ |
8 | 8 | = link_to 'Files', project_tree_path(@project, @ref || @repository.root_ref) |
9 | 9 | |
10 | 10 | - if project_nav_tab? :commits |
11 | - = nav_link(controller: %w(commit commits compare repositories protected_branches tags branches)) do | |
11 | + = nav_link(controller: %w(commit commits compare repositories tags branches)) do | |
12 | 12 | = link_to "Commits", project_commits_path(@project, @ref || @repository.root_ref) |
13 | 13 | |
14 | 14 | - if project_nav_tab? :network | ... | ... |
app/views/projects/_settings_nav.html.haml
app/views/projects/branches/_branch.html.haml
... | ... | @@ -8,6 +8,7 @@ |
8 | 8 | - if @project.protected_branch? branch.name |
9 | 9 | %span.label.label-success |
10 | 10 | %i.icon-lock |
11 | + protected | |
11 | 12 | .pull-right |
12 | 13 | - if can?(current_user, :download_code, @project) |
13 | 14 | = render 'projects/repositories/download_archive', ref: branch.name, btn_class: 'btn-grouped btn-group-small' |
... | ... | @@ -21,13 +22,8 @@ |
21 | 22 | %i.icon-trash |
22 | 23 | |
23 | 24 | - if commit |
24 | - %p | |
25 | - = link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do | |
26 | - = commit.short_id | |
27 | - = image_tag avatar_icon(commit.author_email), class: "avatar s16", alt: '' | |
28 | - %span.light | |
29 | - = gfm escape_once(truncate(commit.title, length: 40)) | |
30 | - #{time_ago_with_tooltip(commit.committed_date)} | |
25 | + %ul.list-unstyled | |
26 | + = render 'projects/commits/inline_commit', commit: commit, project: @project | |
31 | 27 | - else |
32 | 28 | %p |
33 | 29 | Cant find HEAD commit for this branch | ... | ... |
app/views/projects/branches/_filter.html.haml
... | ... | @@ -1,27 +0,0 @@ |
1 | -%ul.nav.nav-pills.nav-stacked | |
2 | - = nav_link(path: 'branches#recent') do | |
3 | - = link_to recent_project_branches_path(@project) do | |
4 | - Recent | |
5 | - .pull-right | |
6 | - = @repository.recent_branches.count | |
7 | - | |
8 | - = nav_link(path: 'protected_branches#index') do | |
9 | - = link_to project_protected_branches_path(@project) do | |
10 | - Protected | |
11 | - %i.icon-lock | |
12 | - .pull-right | |
13 | - = @project.protected_branches.count | |
14 | - | |
15 | - = nav_link(path: 'branches#index') do | |
16 | - = link_to project_branches_path(@project) do | |
17 | - All branches | |
18 | - .pull-right | |
19 | - = @repository.branch_names.count | |
20 | - | |
21 | - | |
22 | -%hr | |
23 | -- if can? current_user, :push_code, @project | |
24 | - = link_to new_project_branch_path(@project), class: 'btn btn-create' do | |
25 | - %i.icon-add-sign | |
26 | - New branch | |
27 | - |
app/views/projects/branches/index.html.haml
1 | 1 | = render "projects/commits/head" |
2 | -.row | |
3 | - .col-md-3 | |
4 | - = render "filter" | |
5 | - .col-md-9 | |
6 | - - unless @branches.empty? | |
7 | - %ul.bordered-list.top-list.all-branches | |
8 | - - @branches.each do |branch| | |
9 | - = render "projects/branches/branch", branch: branch | |
10 | - = paginate @branches, theme: 'gitlab' | |
2 | +%h3.page-title | |
3 | + Branches | |
4 | + .pull-right | |
5 | + - if can? current_user, :push_code, @project | |
6 | + = link_to new_project_branch_path(@project), class: 'btn btn-create' do | |
7 | + %i.icon-add-sign | |
8 | + New branch | |
9 | + | |
10 | + .dropdown.inline | |
11 | + %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} | |
12 | + %span.light sort: | |
13 | + - if @sort.present? | |
14 | + = @sort.humanize | |
15 | + - else | |
16 | + Name | |
17 | + %b.caret | |
18 | + %ul.dropdown-menu | |
19 | + %li | |
20 | + = link_to project_branches_path(sort: nil) do | |
21 | + Name | |
22 | + = link_to project_branches_path(sort: 'recently_updated') do | |
23 | + Recently updated | |
24 | + = link_to project_branches_path(sort: 'last_updated') do | |
25 | + Last updated | |
26 | +%hr | |
27 | +- unless @branches.empty? | |
28 | + %ul.bordered-list.top-list.all-branches | |
29 | + - @branches.each do |branch| | |
30 | + = render "projects/branches/branch", branch: branch | |
31 | + = paginate @branches, theme: 'gitlab' | ... | ... |
app/views/projects/branches/recent.html.haml
app/views/projects/commits/_head.html.haml
... | ... | @@ -7,9 +7,9 @@ |
7 | 7 | = link_to 'Compare', project_compare_index_path(@project, from: @repository.root_ref, to: @ref || @repository.root_ref) |
8 | 8 | |
9 | 9 | = nav_link(html_options: {class: branches_tab_class}) do |
10 | - = link_to recent_project_branches_path(@project) do | |
10 | + = link_to project_branches_path(@project) do | |
11 | 11 | Branches |
12 | - %span.badge= @repository.branches.length | |
12 | + %span.badge= @repository.branches.size | |
13 | 13 | |
14 | 14 | = nav_link(controller: :tags) do |
15 | 15 | = link_to project_tags_path(@project) do | ... | ... |
app/views/projects/protected_branches/index.html.haml
1 | -= render "projects/commits/head" | |
2 | -.row | |
3 | - .col-md-3 | |
4 | - = render "projects/branches/filter" | |
5 | - .col-md-9 | |
6 | - .bs-callout.bs-callout-info | |
7 | - %p Protected branches designed to | |
8 | - %ul | |
9 | - %li prevent push for all except #{link_to "masters", help_permissions_path, class: "vlink"}. | |
10 | - %li prevent branch from force push | |
11 | - %li prevent branch from removal | |
12 | - %p This ability allows to keep stable branches secured and force code review before merge to protected branches | |
13 | - %p Read more about project permissions #{link_to "here", help_permissions_path, class: "underlined-link"} | |
1 | +%h3.page-title Protected branches | |
2 | +%p.light This ability allows to keep stable branches secured and force code review before merge to protected branches | |
3 | +%hr | |
14 | 4 | |
15 | - - if can? current_user, :admin_project, @project | |
16 | - = form_for [@project, @protected_branch], html: { class: 'form-horizontal' } do |f| | |
17 | - -if @protected_branch.errors.any? | |
18 | - .alert.alert-danger | |
19 | - %ul | |
20 | - - @protected_branch.errors.full_messages.each do |msg| | |
21 | - %li= msg | |
5 | +.bs-callout.bs-callout-info | |
6 | + %p Protected branches designed to | |
7 | + %ul | |
8 | + %li prevent push for all except #{link_to "masters", help_permissions_path, class: "vlink"}. | |
9 | + %li prevent branch from force push | |
10 | + %li prevent branch from removal | |
11 | + %p Read more about project permissions #{link_to "here", help_permissions_path, class: "underlined-link"} | |
22 | 12 | |
23 | - .form-group | |
24 | - = f.label :name, "Branch", class: 'control-label' | |
25 | - .col-sm-10 | |
26 | - = f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , {include_blank: "Select branch"}, {class: "select2"}) | |
27 | - .form-actions | |
28 | - = f.submit 'Protect', class: "btn-create btn" | |
29 | - - unless @branches.empty? | |
30 | - %h5 Already Protected: | |
31 | - %ul.bordered-list.protected-branches-list | |
32 | - - @branches.each do |branch| | |
33 | - %li | |
34 | - %h4 | |
35 | - = link_to project_commits_path(@project, branch.name) do | |
36 | - %strong= branch.name | |
37 | - - if @project.root_ref?(branch.name) | |
38 | - %span.label.label-info default | |
39 | - %span.label.label-success | |
40 | - %i.icon-lock | |
41 | - .pull-right | |
42 | - - if can? current_user, :admin_project, @project | |
43 | - = link_to 'Unprotect', [@project, branch], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn btn-remove btn-small" | |
13 | +- if can? current_user, :admin_project, @project | |
14 | + = form_for [@project, @protected_branch], html: { class: 'form-horizontal' } do |f| | |
15 | + -if @protected_branch.errors.any? | |
16 | + .alert.alert-danger | |
17 | + %ul | |
18 | + - @protected_branch.errors.full_messages.each do |msg| | |
19 | + %li= msg | |
44 | 20 | |
45 | - - if commit = branch.commit | |
46 | - = link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do | |
47 | - = commit.short_id | |
48 | - %span.light | |
49 | - = gfm escape_once(truncate(commit.title, length: 40)) | |
50 | - #{time_ago_with_tooltip(commit.committed_date)} | |
51 | - - else | |
52 | - (branch was removed from repository) | |
21 | + .form-group | |
22 | + = f.label :name, "Branch", class: 'control-label' | |
23 | + .col-sm-10 | |
24 | + = f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , {include_blank: "Select branch"}, {class: "select2"}) | |
25 | + .form-actions | |
26 | + = f.submit 'Protect', class: "btn-create btn" | |
27 | +- unless @branches.empty? | |
28 | + %h5 Already Protected: | |
29 | + %ul.bordered-list.protected-branches-list | |
30 | + - @branches.each do |branch| | |
31 | + %li | |
32 | + %h4 | |
33 | + = link_to project_commits_path(@project, branch.name) do | |
34 | + %strong= branch.name | |
35 | + - if @project.root_ref?(branch.name) | |
36 | + %span.label.label-info default | |
37 | + %span.label.label-success | |
38 | + %i.icon-lock | |
39 | + .pull-right | |
40 | + - if can? current_user, :admin_project, @project | |
41 | + = link_to 'Unprotect', [@project, branch], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn btn-remove btn-small" | |
42 | + | |
43 | + - if commit = branch.commit | |
44 | + = link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do | |
45 | + = commit.short_id | |
46 | + %span.light | |
47 | + = gfm escape_once(truncate(commit.title, length: 40)) | |
48 | + #{time_ago_with_tooltip(commit.committed_date)} | |
49 | + - else | |
50 | + (branch was removed from repository) | ... | ... |
config/routes.rb
... | ... | @@ -243,12 +243,7 @@ Gitlab::Application.routes.draw do |
243 | 243 | end |
244 | 244 | end |
245 | 245 | |
246 | - resources :branches, only: [:index, :new, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } do | |
247 | - collection do | |
248 | - get :recent, constraints: { id: Gitlab::Regex.git_reference_regex } | |
249 | - end | |
250 | - end | |
251 | - | |
246 | + resources :branches, only: [:index, :new, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } | |
252 | 247 | resources :tags, only: [:index, :new, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } |
253 | 248 | resources :protected_branches, only: [:index, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } |
254 | 249 | ... | ... |