Commit 64d8a38b authored by Jacob Vosmaer's avatar Jacob Vosmaer

Merge branch 'master' of https://gitlab.com/gitlab-org/gitlab-ce into git-archive-refactor

parents b3bd7c19 28d42a33
...@@ -118,3 +118,19 @@ body { ...@@ -118,3 +118,19 @@ body {
@include gitlab-theme(#9988CC, $theme-violet, #443366, #332255); @include gitlab-theme(#9988CC, $theme-violet, #443366, #332255);
} }
} }
::-webkit-scrollbar{
width: 3px;
}
::-webkit-scrollbar-thumb{
background-color:$theme-charcoal; border-radius: 0;
}
::-webkit-scrollbar-thumb:hover{
background-color:$theme-charcoal;
}
::-webkit-scrollbar-track{
background-color:#FFF;
}
\ No newline at end of file
...@@ -12,6 +12,14 @@ ...@@ -12,6 +12,14 @@
.identifier { .identifier {
color: #5c5d5e; color: #5c5d5e;
} }
.issue_created_ago, .author_link {
white-space: nowrap;
}
.issue-meta {
margin-left: 65px
}
} }
.detail-page-description { .detail-page-description {
......
...@@ -238,6 +238,15 @@ class Repository ...@@ -238,6 +238,15 @@ class Repository
expire_branch_cache(branch_name) expire_branch_cache(branch_name)
end end
# Expires _all_ caches, including those that would normally only be expired
# under specific conditions.
def expire_all_caches!
expire_cache
expire_root_ref_cache
expire_emptiness_caches
expire_has_visible_content_cache
end
def expire_branch_cache(branch_name = nil) def expire_branch_cache(branch_name = nil)
# When we push to the root branch we have to flush the cache for all other # When we push to the root branch we have to flush the cache for all other
# branches as their statistics are based on the commits relative to the # branches as their statistics are based on the commits relative to the
...@@ -258,6 +267,14 @@ class Repository ...@@ -258,6 +267,14 @@ class Repository
@root_ref = nil @root_ref = nil
end end
# Expires the cache(s) used to determine if a repository is empty or not.
def expire_emptiness_caches
cache.expire(:empty?)
@empty = nil
expire_has_visible_content_cache
end
def expire_has_visible_content_cache def expire_has_visible_content_cache
cache.expire(:has_visible_content?) cache.expire(:has_visible_content?)
@has_visible_content = nil @has_visible_content = nil
...@@ -611,6 +628,8 @@ class Repository ...@@ -611,6 +628,8 @@ class Repository
end end
def merge_base(first_commit_id, second_commit_id) def merge_base(first_commit_id, second_commit_id)
first_commit_id = commit(first_commit_id).try(:id) || first_commit_id
second_commit_id = commit(second_commit_id).try(:id) || second_commit_id
rugged.merge_base(first_commit_id, second_commit_id) rugged.merge_base(first_commit_id, second_commit_id)
rescue Rugged::ReferenceError rescue Rugged::ReferenceError
nil nil
......
...@@ -16,11 +16,15 @@ module Projects ...@@ -16,11 +16,15 @@ module Projects
return false unless can?(current_user, :remove_project, project) return false unless can?(current_user, :remove_project, project)
project.team.truncate project.team.truncate
project.repository.expire_cache unless project.empty_repo?
repo_path = project.path_with_namespace repo_path = project.path_with_namespace
wiki_path = repo_path + '.wiki' wiki_path = repo_path + '.wiki'
# Flush the cache for both repositories. This has to be done _before_
# removing the physical repositories as some expiration code depends on
# Git data (e.g. a list of branch names).
flush_caches(project, wiki_path)
Project.transaction do Project.transaction do
project.destroy! project.destroy!
...@@ -70,5 +74,13 @@ module Projects ...@@ -70,5 +74,13 @@ module Projects
def removal_path(path) def removal_path(path)
"#{path}+#{project.id}#{DELETED_FLAG}" "#{path}+#{project.id}#{DELETED_FLAG}"
end end
def flush_caches(project, wiki_path)
project.repository.expire_all_caches! if project.repository.exists?
wiki_repo = Repository.new(wiki_path, project)
wiki_repo.expire_all_caches! if wiki_repo.exists?
end
end end
end end
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
= render "download", blob: blob = render "download", blob: blob
- elsif blob.text? - elsif blob.text?
- if blob_svg?(blob) - if blob_svg?(blob)
= render "image", blob: sanitize_svg(blob) = render "image", blob: blob
- else - else
= render "text", blob: blob = render "text", blob: blob
- elsif blob.image? - elsif blob.image?
......
.file-content.image_file .file-content.image_file
%img{ src: namespace_project_raw_path(@project.namespace, @project, @id)} - if blob_svg?(blob)
- # We need to scrub SVG but we cannot do so in the RawController: it would
- # be wrong/strange if RawController modified the data.
- blob.load_all_data!(@repository)
- blob = sanitize_svg(blob)
%img{src: "data:#{blob.mime_type};base64,#{Base64.encode64(blob.data)}"}
- else
%img{src: namespace_project_raw_path(@project.namespace, @project, @id)}
- diff = diff_file.diff - diff = diff_file.diff
- file.load_all_data!(@project.repository) - file_raw_path = namespace_project_raw_path(@project.namespace, @project, tree_join(@commit.id, diff.new_path))
- old_file_raw_path = namespace_project_raw_path(@project.namespace, @project, tree_join(@commit.parent_id, diff.old_path))
- if diff.renamed_file || diff.new_file || diff.deleted_file - if diff.renamed_file || diff.new_file || diff.deleted_file
.image .image
%span.wrap %span.wrap
.frame{class: image_diff_class(diff)} .frame{class: image_diff_class(diff)}
%img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} %img{src: diff.deleted_file ? old_file_raw_path : file_raw_path}
%p.image-info= "#{number_to_human_size file.size}" %p.image-info= "#{number_to_human_size file.size}"
- else - else
- old_file.load_all_data!(@project.repository)
.image .image
%div.two-up.view %div.two-up.view
%span.wrap %span.wrap
.frame.deleted .frame.deleted
%a{href: namespace_project_blob_path(@project.namespace, @project, tree_join(@commit.parent_id, diff.old_path))} %a{href: namespace_project_blob_path(@project.namespace, @project, tree_join(@commit.parent_id, diff.old_path))}
%img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"} %img{src: old_file_raw_path}
%p.image-info.hide %p.image-info.hide
%span.meta-filesize= "#{number_to_human_size old_file.size}" %span.meta-filesize= "#{number_to_human_size old_file.size}"
| |
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
%span.wrap %span.wrap
.frame.added .frame.added
%a{href: namespace_project_blob_path(@project.namespace, @project, tree_join(@commit.id, diff.new_path))} %a{href: namespace_project_blob_path(@project.namespace, @project, tree_join(@commit.id, diff.new_path))}
%img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} %img{src: file_raw_path}
%p.image-info.hide %p.image-info.hide
%span.meta-filesize= "#{number_to_human_size file.size}" %span.meta-filesize= "#{number_to_human_size file.size}"
| |
...@@ -38,10 +38,10 @@ ...@@ -38,10 +38,10 @@
%div.swipe.view.hide %div.swipe.view.hide
.swipe-frame .swipe-frame
.frame.deleted .frame.deleted
%img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"} %img{src: old_file_raw_path}
.swipe-wrap .swipe-wrap
.frame.added .frame.added
%img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} %img{src: file_raw_path}
%span.swipe-bar %span.swipe-bar
%span.top-handle %span.top-handle
%span.bottom-handle %span.bottom-handle
...@@ -49,9 +49,9 @@ ...@@ -49,9 +49,9 @@
%div.onion-skin.view.hide %div.onion-skin.view.hide
.onion-skin-frame .onion-skin-frame
.frame.deleted .frame.deleted
%img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"} %img{src: old_file_raw_path}
.frame.added .frame.added
%img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} %img{src: file_raw_path}
.controls .controls
.transparent .transparent
.drag-track .drag-track
......
...@@ -6,16 +6,6 @@ ...@@ -6,16 +6,6 @@
.issue .issue
.detail-page-header .detail-page-header
.status-box{ class: "status-box-closed #{issue_button_visibility(@issue, false)}"} Closed
.status-box{ class: "status-box-open #{issue_button_visibility(@issue, true)}"} Open
%span.identifier
Issue ##{@issue.iid}
%span.creator
·
opened by #{link_to_member(@project, @issue.author, size: 24)}
·
= time_ago_with_tooltip(@issue.created_at, placement: 'bottom', html_class: 'issue_created_ago')
.pull-right .pull-right
- if can?(current_user, :create_issue, @project) - if can?(current_user, :create_issue, @project)
= link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'btn btn-nr btn-grouped new-issue-link btn-success', title: 'New Issue', id: 'new_issue_link' do = link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'btn btn-nr btn-grouped new-issue-link btn-success', title: 'New Issue', id: 'new_issue_link' do
...@@ -29,6 +19,19 @@ ...@@ -29,6 +19,19 @@
= icon('pencil-square-o') = icon('pencil-square-o')
Edit Edit
.pull-left
.status-box{ class: "status-box-closed #{issue_button_visibility(@issue, false)}"} Closed
.status-box{ class: "status-box-open #{issue_button_visibility(@issue, true)}"} Open
.issue-meta
%span.identifier
Issue ##{@issue.iid}
%span.creator
·
by #{link_to_member(@project, @issue.author, size: 24)}
·
= time_ago_with_tooltip(@issue.created_at, placement: 'bottom', html_class: 'issue_created_ago')
.issue-details.issuable-details .issue-details.issuable-details
.detail-page-description.content-block .detail-page-description.content-block
%h2.title %h2.title
......
$('aside.right-sidebar')[0].outerHTML = "#{escape_javascript(render 'shared/issuable/sidebar', issuable: @issue)}"; $('aside.right-sidebar')[0].outerHTML = "#{escape_javascript(render 'shared/issuable/sidebar', issuable: @issue)}";
$('aside.right-sidebar').effect('highlight'); $('aside.right-sidebar').effect('highlight');
new Issue(); new IssuableContext();
\ No newline at end of file
$('aside.right-sidebar')[0].outerHTML= "#{escape_javascript(render 'shared/issuable/sidebar', issuable: @merge_request)}"; $('aside.right-sidebar')[0].outerHTML = "#{escape_javascript(render 'shared/issuable/sidebar', issuable: @merge_request)}";
$('aside.right-sidebar').effect('highlight') $('aside.right-sidebar').effect('highlight');
merge_request = new MergeRequest(); new IssuableContext();
...@@ -27,6 +27,7 @@ class RepositoryForkWorker ...@@ -27,6 +27,7 @@ class RepositoryForkWorker
return return
end end
project.repository.expire_emptiness_caches
project.import_finish project.import_finish
end end
end end
...@@ -18,6 +18,7 @@ class RepositoryImportWorker ...@@ -18,6 +18,7 @@ class RepositoryImportWorker
return return
end end
project.repository.expire_emptiness_caches
project.import_finish project.import_finish
end end
end end
...@@ -22,6 +22,8 @@ module Gitlab ...@@ -22,6 +22,8 @@ module Gitlab
# } # }
# #
def build(project, user, oldrev, newrev, ref, commits = [], message = nil) def build(project, user, oldrev, newrev, ref, commits = [], message = nil)
commits = Array(commits)
# Total commits count # Total commits count
commits_count = commits.size commits_count = commits.size
......
require 'spec_helper' require 'spec_helper'
describe 'Gitlab::PushDataBuilder', lib: true do describe Gitlab::PushDataBuilder, lib: true do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:user) { create(:user) } let(:user) { create(:user) }
describe :build_sample do describe '.build_sample' do
let(:data) { Gitlab::PushDataBuilder.build_sample(project, user) } let(:data) { described_class.build_sample(project, user) }
it { expect(data).to be_a(Hash) } it { expect(data).to be_a(Hash) }
it { expect(data[:before]).to eq('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') } it { expect(data[:before]).to eq('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') }
...@@ -22,11 +22,9 @@ describe 'Gitlab::PushDataBuilder', lib: true do ...@@ -22,11 +22,9 @@ describe 'Gitlab::PushDataBuilder', lib: true do
include_examples 'deprecated repository hook data' include_examples 'deprecated repository hook data'
end end
describe :build do describe '.build' do
let(:data) do let(:data) do
Gitlab::PushDataBuilder.build(project, described_class.build(project, user, Gitlab::Git::BLANK_SHA,
user,
Gitlab::Git::BLANK_SHA,
'8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b', '8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b',
'refs/tags/v1.1.0') 'refs/tags/v1.1.0')
end end
...@@ -38,5 +36,10 @@ describe 'Gitlab::PushDataBuilder', lib: true do ...@@ -38,5 +36,10 @@ describe 'Gitlab::PushDataBuilder', lib: true do
it { expect(data[:ref]).to eq('refs/tags/v1.1.0') } it { expect(data[:ref]).to eq('refs/tags/v1.1.0') }
it { expect(data[:commits]).to be_empty } it { expect(data[:commits]).to be_empty }
it { expect(data[:total_commits_count]).to be_zero } it { expect(data[:total_commits_count]).to be_zero }
it 'does not raise an error when given nil commits' do
expect { described_class.build(spy, spy, spy, spy, spy, nil) }.
not_to raise_error
end
end end
end end
...@@ -355,6 +355,17 @@ describe Repository, models: true do ...@@ -355,6 +355,17 @@ describe Repository, models: true do
end end
end end
describe '#expire_emptiness_caches' do
let(:cache) { repository.send(:cache) }
it 'expires the caches' do
expect(cache).to receive(:expire).with(:empty?)
expect(repository).to receive(:expire_has_visible_content_cache)
repository.expire_emptiness_caches
end
end
describe :skip_merged_commit do describe :skip_merged_commit do
subject { repository.commits(Gitlab::Git::BRANCH_REF_PREFIX + "'test'", nil, 100, 0, true).map{ |k| k.id } } subject { repository.commits(Gitlab::Git::BRANCH_REF_PREFIX + "'test'", nil, 100, 0, true).map{ |k| k.id } }
......
...@@ -19,6 +19,18 @@ describe RepositoryForkWorker do ...@@ -19,6 +19,18 @@ describe RepositoryForkWorker do
fork_project.namespace.path) fork_project.namespace.path)
end end
it 'flushes the empty caches' do
expect_any_instance_of(Gitlab::Shell).to receive(:fork_repository).
with(project.path_with_namespace, fork_project.namespace.path).
and_return(true)
expect_any_instance_of(Repository).to receive(:expire_emptiness_caches).
and_call_original
subject.perform(project.id, project.path_with_namespace,
fork_project.namespace.path)
end
it "handles bad fork" do it "handles bad fork" do
expect_any_instance_of(Gitlab::Shell).to receive(:fork_repository).and_return(false) expect_any_instance_of(Gitlab::Shell).to receive(:fork_repository).and_return(false)
subject.perform( subject.perform(
......
require 'spec_helper'
describe RepositoryImportWorker do
let(:project) { create(:project) }
subject { described_class.new }
describe '#perform' do
it 'imports a project' do
expect_any_instance_of(Projects::ImportService).to receive(:execute).
and_return({ status: :ok })
expect_any_instance_of(Repository).to receive(:expire_emptiness_caches)
expect_any_instance_of(Project).to receive(:import_finish)
subject.perform(project.id)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment