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 | 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 | ... | ... |