diff --git a/CHANGELOG b/CHANGELOG index 94a776a35eb..879d057fff0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -23,6 +23,7 @@ v 8.4.0 (unreleased) - Validate README format before displaying - Enable Microsoft Azure OAuth2 support (Janis Meybohm) - Add file finder feature in tree view (koreamic) + - Ajax filter by message for commits page v 8.3.3 (unreleased) - Get "Merge when build succeeds" to work when commits were pushed to MR target branch while builds were running diff --git a/app/assets/javascripts/commits.js.coffee b/app/assets/javascripts/commits.js.coffee index c183e78e513..ffd3627b1b0 100644 --- a/app/assets/javascripts/commits.js.coffee +++ b/app/assets/javascripts/commits.js.coffee @@ -1,15 +1,5 @@ class @CommitsList - @data = - ref: null - limit: 0 - offset: 0 - @disable = false - - @showProgress: -> - $('.loading').show() - - @hideProgress: -> - $('.loading').hide() + @timer = null @init: (ref, limit) -> $("body").on "click", ".day-commits-table li.commit", (event) -> @@ -18,38 +8,32 @@ class @CommitsList e.stopPropagation() return false - @data.ref = ref - @data.limit = limit - @data.offset = limit + Pager.init limit, false - this.initLoadMore() - this.showProgress() + @content = $("#commits-list") + @searchField = $("#commits-search") + @initSearch() + + @initSearch: -> + @timer = null + @searchField.keyup => + clearTimeout(@timer) + @timer = setTimeout(@filterResults, 500) + + @filterResults: => + form = $(".commits-search-form") + search = @searchField.val() + commitsUrl = form.attr("action") + '?' + form.serialize() + @content.fadeTo('fast', 0.5) - @getOld: -> - this.showProgress() $.ajax type: "GET" - url: location.href - data: @data - complete: this.hideProgress - success: (data) -> - CommitsList.append(data.count, data.html) + url: form.attr("action") + data: form.serialize() + complete: => + @content.fadeTo('fast', 1.0) + success: (data) => + @content.html(data.html) + # Change url so if user reload a page - search results are saved + history.replaceState {page: commitsUrl}, document.title, commitsUrl dataType: "json" - - @append: (count, html) -> - $("#commits-list").append(html) - if count > 0 - @data.offset += count - else - @disable = true - - @initLoadMore: -> - $(document).unbind('scroll') - $(document).endlessScroll - bottomPixels: 400 - fireDelay: 1000 - fireOnce: true - ceaseFire: => - @disable - callback: => - this.getOld() diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index 206d39cc9b3..fa0e70847f3 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -72,6 +72,15 @@ > p:last-child { margin-bottom: 0; } + + .block-controls { + float: right; + + .control { + float: left; + margin-left: 10px; + } + } } .cover-block { diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index 879bd287470..800df95cff3 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -28,10 +28,6 @@ } } -.commits-feed-holder { - float: right; -} - li.commit { list-style: none; @@ -126,14 +122,14 @@ li.commit { .divergence-graph { padding: 12px 12px 0 0; float: right; - + .graph-side { position: relative; width: 80px; height: 22px; padding: 5px 0 13px; float: left; - + .bar { position: absolute; height: 4px; @@ -149,7 +145,7 @@ li.commit { left: 0; border-radius: 0 3px 3px 0; } - + .count { padding-top: 6px; padding-bottom: 0px; diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb index 04a88990bf4..bf5b54c8cb7 100644 --- a/app/controllers/projects/commits_controller.rb +++ b/app/controllers/projects/commits_controller.rb @@ -8,10 +8,16 @@ class Projects::CommitsController < Projects::ApplicationController before_action :authorize_download_code! def show - @repo = @project.repository @limit, @offset = (params[:limit] || 40).to_i, (params[:offset] || 0).to_i + search = params[:search] + + @commits = + if search.present? + @repository.find_commits_by_message(search, @ref, @path, @limit, @offset).compact + else + @repository.commits(@ref, @path, @limit, @offset) + end - @commits = @repo.commits(@ref, @path, @limit, @offset) @note_counts = project.notes.where(commit_id: @commits.map(&:id)). group(:commit_id).count diff --git a/app/models/repository.rb b/app/models/repository.rb index 9deb08d93b8..d9ff71c01ed 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -92,9 +92,12 @@ class Repository commits end - def find_commits_by_message(query) + def find_commits_by_message(query, ref = nil, path = nil, limit = 1000, offset = 0) + ref ||= root_ref + # Limited to 1000 commits for now, could be parameterized? - args = %W(#{Gitlab.config.git.bin_path} log --pretty=%H --max-count 1000 --grep=#{query}) + args = %W(#{Gitlab.config.git.bin_path} log #{ref} --pretty=%H --skip #{offset} --max-count #{limit} --grep=#{query}) + args = args.concat(%W(-- #{path})) if path.present? git_log_results = Gitlab::Popen.popen(args, path_to_repo).first.lines.map(&:chomp) commits = git_log_results.map { |c| commit(c) } @@ -175,7 +178,7 @@ class Repository def size cache.fetch(:size) { raw_repository.size } end - + def diverging_commit_counts(branch) root_ref_hash = raw_repository.rev_parse_target(root_ref).oid cache.fetch(:"diverging_commit_counts_#{branch.name}") do @@ -183,7 +186,7 @@ class Repository # than SHA-1 hashes number_commits_behind = commits_between(branch.target, root_ref_hash).size number_commits_ahead = commits_between(root_ref_hash, branch.target).size - + { behind: number_commits_behind, ahead: number_commits_ahead } end end @@ -192,7 +195,7 @@ class Repository %i(size branch_names tag_names commit_count readme version contribution_guide changelog license) end - + def branch_cache_keys branches.map do |branch| :"diverging_commit_counts_#{branch.name}" @@ -205,7 +208,7 @@ class Repository send(key) end end - + branches.each do |branch| unless cache.exist?(:"diverging_commit_counts_#{branch.name}") send(:diverging_commit_counts, branch) @@ -227,10 +230,10 @@ class Repository cache_keys.each do |key| cache.expire(key) end - + expire_branch_cache end - + def expire_branch_cache branches.each do |branch| cache.expire(:"diverging_commit_counts_#{branch.name}") @@ -242,7 +245,7 @@ class Repository cache.expire(key) send(key) end - + branches.each do |branch| cache.expire(:"diverging_commit_counts_#{branch.name}") diverging_commit_counts(branch) diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml index 2dd99cc8215..034057da42e 100644 --- a/app/views/projects/commits/show.html.haml +++ b/app/views/projects/commits/show.html.haml @@ -10,26 +10,30 @@ .tree-ref-holder = render 'shared/ref_switcher', destination: 'commits' - .commits-feed-holder.hidden-xs.hidden-sm + .block-controls.hidden-xs.hidden-sm - if create_mr_button?(@repository.root_ref, @ref) - = link_to create_mr_path(@repository.root_ref, @ref), class: 'btn btn-success' do - = icon('plus') - Create Merge Request + .control + = link_to create_mr_path(@repository.root_ref, @ref), class: 'btn btn-success' do + = icon('plus') + Create Merge Request + + .control + = form_tag(namespace_project_commits_path(@project.namespace, @project, @id), method: :get, class: 'pull-left commits-search-form') do + = search_field_tag :search, params[:search], { placeholder: 'Filter by commit message', id: 'commits-search', class: 'form-control search-text-input', spellcheck: false } - if current_user && current_user.private_token - = link_to namespace_project_commits_path(@project.namespace, @project, @ref, {format: :atom, private_token: current_user.private_token}), title: "Commits Feed", class: 'prepend-left-10 btn' do - = icon("rss") + .control + = link_to namespace_project_commits_path(@project.namespace, @project, @ref, {format: :atom, private_token: current_user.private_token}), title: "Commits Feed", class: 'btn' do + = icon("rss") %ul.breadcrumb.repo-breadcrumb = commits_breadcrumbs %div{id: dom_id(@project)} - #commits-list= render "commits", project: @project + #commits-list.content_list= render "commits", project: @project .clear = spinner -- if @commits.count == @limit - :javascript - CommitsList.init("#{@ref}", #{@limit}); - +:javascript + CommitsList.init("#{@ref}", #{@limit}); diff --git a/features/project/commits/commits.feature b/features/project/commits/commits.feature index 5bb2d0e976b..01c10721312 100644 --- a/features/project/commits/commits.feature +++ b/features/project/commits/commits.feature @@ -55,3 +55,8 @@ Feature: Project Commits Scenario: I browse a commit with an image Given I visit a commit with an image that changed Then The diff links to both the previous and current image + + @javascript + Scenario: I filter commits by message + When I search "submodules" commits + Then I should see only "submodules" commits diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb index a3141fe3be1..daf6cdaaac8 100644 --- a/features/steps/project/commits/commits.rb +++ b/features/steps/project/commits/commits.rb @@ -124,4 +124,13 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps expect(page).to have_content "build: pending" expect(page).to have_content "1 build" end + + step 'I search "submodules" commits' do + fill_in 'commits-search', with: 'submodules' + end + + step 'I should see only "submodules" commits' do + expect(page).to have_content "More submodules" + expect(page).not_to have_content "Change some files" + end end