Commit 695fd3cf2c7e01d06e9c335cae208089a4c6bfbd
1 parent
8ae2d215
Exists in
spb-stable
and in
2 other branches
Move protected branches to Project settings
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
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 +7,9 @@ class Projects::BranchesController < Projects::ApplicationController | ||
7 | before_filter :authorize_push!, only: [:create, :destroy] | 7 | before_filter :authorize_push!, only: [:create, :destroy] |
8 | 8 | ||
9 | def index | 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 | end | 13 | end |
12 | 14 | ||
13 | def recent | 15 | def recent |
app/controllers/projects/protected_branches_controller.rb
1 | class Projects::ProtectedBranchesController < Projects::ApplicationController | 1 | class Projects::ProtectedBranchesController < Projects::ApplicationController |
2 | # Authorize | 2 | # Authorize |
3 | - before_filter :authorize_read_project! | ||
4 | before_filter :require_non_empty_project | 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 | def index | 8 | def index |
9 | @branches = @project.protected_branches.to_a | 9 | @branches = @project.protected_branches.to_a |
app/helpers/tab_helper.rb
@@ -75,7 +75,7 @@ module TabHelper | @@ -75,7 +75,7 @@ module TabHelper | ||
75 | def project_tab_class | 75 | def project_tab_class |
76 | return "active" if current_page?(controller: "/projects", action: :edit, id: @project) | 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 | "active" | 79 | "active" |
80 | end | 80 | end |
81 | end | 81 | end |
app/models/repository.rb
@@ -55,12 +55,6 @@ class Repository | @@ -55,12 +55,6 @@ class Repository | ||
55 | tags.find { |tag| tag.name == name } | 55 | tags.find { |tag| tag.name == name } |
56 | end | 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 | def add_branch(branch_name, ref) | 58 | def add_branch(branch_name, ref) |
65 | Rails.cache.delete(cache_key(:branch_names)) | 59 | Rails.cache.delete(cache_key(:branch_names)) |
66 | 60 | ||
@@ -220,4 +214,19 @@ class Repository | @@ -220,4 +214,19 @@ class Repository | ||
220 | def clean_old_archives | 214 | def clean_old_archives |
221 | Gitlab::Popen.popen(%W(find #{Gitlab.config.gitlab.repository_downloads_path} -mmin +120 -delete)) | 215 | Gitlab::Popen.popen(%W(find #{Gitlab.config.gitlab.repository_downloads_path} -mmin +120 -delete)) |
222 | end | 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 | end | 232 | end |
app/views/layouts/nav/_project.html.haml
@@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
8 | = link_to 'Files', project_tree_path(@project, @ref || @repository.root_ref) | 8 | = link_to 'Files', project_tree_path(@project, @ref || @repository.root_ref) |
9 | 9 | ||
10 | - if project_nav_tab? :commits | 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 | = link_to "Commits", project_commits_path(@project, @ref || @repository.root_ref) | 12 | = link_to "Commits", project_commits_path(@project, @ref || @repository.root_ref) |
13 | 13 | ||
14 | - if project_nav_tab? :network | 14 | - if project_nav_tab? :network |
app/views/projects/_settings_nav.html.haml
@@ -19,3 +19,7 @@ | @@ -19,3 +19,7 @@ | ||
19 | = link_to project_services_path(@project) do | 19 | = link_to project_services_path(@project) do |
20 | %i.icon-cogs | 20 | %i.icon-cogs |
21 | Services | 21 | Services |
22 | + = nav_link(controller: :protected_branches) do | ||
23 | + = link_to project_protected_branches_path(@project) do | ||
24 | + %i.icon-lock | ||
25 | + Protected branches |
app/views/projects/branches/_branch.html.haml
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | - if @project.protected_branch? branch.name | 8 | - if @project.protected_branch? branch.name |
9 | %span.label.label-success | 9 | %span.label.label-success |
10 | %i.icon-lock | 10 | %i.icon-lock |
11 | + protected | ||
11 | .pull-right | 12 | .pull-right |
12 | - if can?(current_user, :download_code, @project) | 13 | - if can?(current_user, :download_code, @project) |
13 | = render 'projects/repositories/download_archive', ref: branch.name, btn_class: 'btn-grouped btn-group-small' | 14 | = render 'projects/repositories/download_archive', ref: branch.name, btn_class: 'btn-grouped btn-group-small' |
@@ -21,13 +22,8 @@ | @@ -21,13 +22,8 @@ | ||
21 | %i.icon-trash | 22 | %i.icon-trash |
22 | 23 | ||
23 | - if commit | 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 | - else | 27 | - else |
32 | %p | 28 | %p |
33 | Cant find HEAD commit for this branch | 29 | Cant find HEAD commit for this branch |
app/views/projects/branches/_filter.html.haml
@@ -1,27 +0,0 @@ | @@ -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 | = render "projects/commits/head" | 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,9 +7,9 @@ | ||
7 | = link_to 'Compare', project_compare_index_path(@project, from: @repository.root_ref, to: @ref || @repository.root_ref) | 7 | = link_to 'Compare', project_compare_index_path(@project, from: @repository.root_ref, to: @ref || @repository.root_ref) |
8 | 8 | ||
9 | = nav_link(html_options: {class: branches_tab_class}) do | 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 | Branches | 11 | Branches |
12 | - %span.badge= @repository.branches.length | 12 | + %span.badge= @repository.branches.size |
13 | 13 | ||
14 | = nav_link(controller: :tags) do | 14 | = nav_link(controller: :tags) do |
15 | = link_to project_tags_path(@project) do | 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,12 +243,7 @@ Gitlab::Application.routes.draw do | ||
243 | end | 243 | end |
244 | end | 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 | resources :tags, only: [:index, :new, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } | 247 | resources :tags, only: [:index, :new, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } |
253 | resources :protected_branches, only: [:index, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } | 248 | resources :protected_branches, only: [:index, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } |
254 | 249 |