diff options
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | app/models/repository.rb | 34 | ||||
-rw-r--r-- | app/views/search/results/_blob.html.haml | 1 | ||||
-rw-r--r-- | app/views/search/results/_wiki_blob.html.haml | 1 | ||||
-rw-r--r-- | spec/models/repository_spec.rb | 24 |
5 files changed, 61 insertions, 0 deletions
diff --git a/CHANGELOG b/CHANGELOG index 56f6a48cc51..adb1d65c135 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -43,6 +43,7 @@ v 7.13.0 (unreleased) - Redesign project page. Show README as default instead of activity. Move project activity to separate page - Make left menu more hierarchical and less contextual by adding back item at top - A fork can’t have a visibility level that is greater than the original project. + - Faster code search in repository and wiki. Fixes search page timeout for big repositories v 7.12.2 - Correctly show anonymous authorized applications under Profile > Applications. diff --git a/app/models/repository.rb b/app/models/repository.rb index c767d1051d1..6262b5c4c92 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -431,6 +431,40 @@ class Repository end end + def search_files(query, ref) + offset = 2 + args = %W(git grep -i -n --before-context #{offset} --after-context #{offset} #{query} #{ref || root_ref}) + Gitlab::Popen.popen(args, path_to_repo).first.scrub.split(/^--$/) + end + + def parse_search_result(result) + ref = nil + filename = nil + startline = 0 + + lines = result.lines + lines.each_with_index do |line, index| + if line =~ /^.*:.*:\d+:/ + ref, filename, startline = line.split(':') + startline = startline.to_i - index + break + end + end + + data = lines.map do |line| + line.sub(ref, '').sub(filename, '').sub(/^:-\d+-/, '').sub(/^::\d+:/, '') + end + + data = data.join("") + + OpenStruct.new( + filename: filename, + ref: ref, + startline: startline, + data: data + ) + end + private def cache diff --git a/app/views/search/results/_blob.html.haml b/app/views/search/results/_blob.html.haml index 84e9be82c44..58f58eff54d 100644 --- a/app/views/search/results/_blob.html.haml +++ b/app/views/search/results/_blob.html.haml @@ -1,3 +1,4 @@ +- blob = @project.repository.parse_search_result(blob) .blob-result .file-holder .file-title diff --git a/app/views/search/results/_wiki_blob.html.haml b/app/views/search/results/_wiki_blob.html.haml index f9c5810e3d0..c03438eb952 100644 --- a/app/views/search/results/_wiki_blob.html.haml +++ b/app/views/search/results/_wiki_blob.html.haml @@ -1,3 +1,4 @@ +- wiki_blob = @project.repository.parse_search_result(wiki_blob) .blob-result .file-holder .file-title diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index a083dcb1274..d25351b0f0e 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -47,4 +47,28 @@ describe Repository do it { is_expected.to be_falsey } end end + + describe "search_files" do + let(:results) { repository.search_files('feature', 'master') } + subject { results } + + it { is_expected.to be_an Array } + + describe 'result' do + subject { results.first } + + it { is_expected.to be_an String } + it { expect(subject.lines[2]).to eq("master:CHANGELOG:188: - Feature: Replace teams with group membership\n") } + end + + describe 'parsing result' do + subject { repository.parse_search_result(results.first) } + + it { is_expected.to be_an OpenStruct } + it { expect(subject.filename).to eq('CHANGELOG') } + it { expect(subject.ref).to eq('master') } + it { expect(subject.startline).to eq(186) } + it { expect(subject.data.lines[2]).to eq(" - Feature: Replace teams with group membership\n") } + end + end end |