diff options
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/archive_repository_service.rb | 23 | ||||
-rw-r--r-- | app/services/ci/create_builds_service.rb | 1 | ||||
-rw-r--r-- | app/services/git_push_service.rb | 118 | ||||
-rw-r--r-- | app/services/projects/destroy_service.rb | 14 | ||||
-rw-r--r-- | app/services/system_note_service.rb | 19 |
5 files changed, 89 insertions, 86 deletions
diff --git a/app/services/archive_repository_service.rb b/app/services/archive_repository_service.rb deleted file mode 100644 index 2160bf13e6d..00000000000 --- a/app/services/archive_repository_service.rb +++ /dev/null @@ -1,23 +0,0 @@ -class ArchiveRepositoryService - attr_reader :project, :ref, :format - - def initialize(project, ref, format) - format ||= 'tar.gz' - @project, @ref, @format = project, ref, format.downcase - end - - def execute(options = {}) - RepositoryArchiveCacheWorker.perform_async - - metadata = project.repository.archive_metadata(ref, storage_path, format) - raise "Repository or ref not found" if metadata.empty? - - metadata - end - - private - - def storage_path - Gitlab.config.gitlab.repository_downloads_path - end -end diff --git a/app/services/ci/create_builds_service.rb b/app/services/ci/create_builds_service.rb index ad901f2da5d..002f7ba1278 100644 --- a/app/services/ci/create_builds_service.rb +++ b/app/services/ci/create_builds_service.rb @@ -34,6 +34,7 @@ module Ci build = commit.builds.create!(build_attrs) build.execute_hooks + build end end end diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index e3bf14966c8..a1711d234ff 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -1,10 +1,10 @@ -class GitPushService - attr_accessor :project, :user, :push_data, :push_commits +class GitPushService < BaseService + attr_accessor :push_data, :push_commits include Gitlab::CurrentSettings include Gitlab::Access # This method will be called after each git update - # and only if the provided user and project is present in GitLab. + # and only if the provided user and project are present in GitLab. # # All callbacks for post receive action should be placed here. # @@ -15,67 +15,67 @@ class GitPushService # 4. Executes the project's web hooks # 5. Executes the project's services # - def execute(project, user, oldrev, newrev, ref) - @project, @user = project, user - - branch_name = Gitlab::Git.ref_name(ref) - - project.repository.expire_cache(branch_name) - - if push_remove_branch?(ref, newrev) - project.repository.expire_has_visible_content_cache + def execute + @project.repository.expire_cache(branch_name) + if push_remove_branch? + @project.repository.expire_has_visible_content_cache @push_commits = [] - elsif push_to_new_branch?(ref, oldrev) - project.repository.expire_has_visible_content_cache + elsif push_to_new_branch? + @project.repository.expire_has_visible_content_cache # Re-find the pushed commits. - if is_default_branch?(ref) + if is_default_branch? # Initial push to the default branch. Take the full history of that branch as "newly pushed". - @push_commits = project.repository.commits(newrev) - - # Ensure HEAD points to the default branch in case it is not master - project.change_head(branch_name) - - # Set protection on the default branch if configured - if (current_application_settings.default_branch_protection != PROTECTION_NONE) - developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false - project.protected_branches.create({ name: project.default_branch, developers_can_push: developers_can_push }) - end + process_default_branch else # Use the pushed commits that aren't reachable by the default branch # as a heuristic. This may include more commits than are actually pushed, but # that shouldn't matter because we check for existing cross-references later. - @push_commits = project.repository.commits_between(project.default_branch, newrev) + @push_commits = @project.repository.commits_between(@project.default_branch, params[:newrev]) # don't process commits for the initial push to the default branch - process_commit_messages(ref) + process_commit_messages end - elsif push_to_existing_branch?(ref, oldrev) + elsif push_to_existing_branch? # Collect data for this git push - @push_commits = project.repository.commits_between(oldrev, newrev) - process_commit_messages(ref) + @push_commits = @project.repository.commits_between(params[:oldrev], params[:newrev]) + process_commit_messages end - # Update merge requests that may be affected by this push. A new branch # could cause the last commit of a merge request to change. - project.update_merge_requests(oldrev, newrev, ref, @user) + update_merge_requests + end - @push_data = build_push_data(oldrev, newrev, ref) + protected - EventCreateService.new.push(project, user, @push_data) - project.execute_hooks(@push_data.dup, :push_hooks) - project.execute_services(@push_data.dup, :push_hooks) - CreateCommitBuildsService.new.execute(project, @user, @push_data) - ProjectCacheWorker.perform_async(project.id) + def update_merge_requests + @project.update_merge_requests(params[:oldrev], params[:newrev], params[:ref], current_user) + + EventCreateService.new.push(@project, current_user, build_push_data) + @project.execute_hooks(build_push_data.dup, :push_hooks) + @project.execute_services(build_push_data.dup, :push_hooks) + CreateCommitBuildsService.new.execute(@project, current_user, build_push_data) + ProjectCacheWorker.perform_async(@project.id) end - protected + def process_default_branch + @push_commits = project.repository.commits(params[:newrev]) + + # Ensure HEAD points to the default branch in case it is not master + project.change_head(branch_name) + + # Set protection on the default branch if configured + if (current_application_settings.default_branch_protection != PROTECTION_NONE) + developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false + @project.protected_branches.create({ name: @project.default_branch, developers_can_push: developers_can_push }) + end + end # Extract any GFM references from the pushed commit messages. If the configured issue-closing regex is matched, # close the referenced Issue. Create cross-reference Notes corresponding to any other referenced Mentionables. - def process_commit_messages(ref) - is_default_branch = is_default_branch?(ref) + def process_commit_messages + is_default_branch = is_default_branch? authors = Hash.new do |hash, commit| email = commit.author_email @@ -94,7 +94,7 @@ class GitPushService # Close issues if these commits were pushed to the project's default branch and the commit message matches the # closing regex. Exclude any mentioned Issues from cross-referencing even if the commits are being pushed to # a different branch. - closed_issues = commit.closes_issues(user) + closed_issues = commit.closes_issues(current_user) closed_issues.each do |issue| Issues::CloseService.new(project, authors[commit], {}).execute(issue, commit) end @@ -104,34 +104,38 @@ class GitPushService end end - def build_push_data(oldrev, newrev, ref) - Gitlab::PushDataBuilder. - build(project, user, oldrev, newrev, ref, push_commits) + def build_push_data + @push_data ||= Gitlab::PushDataBuilder. + build(@project, current_user, params[:oldrev], params[:newrev], params[:ref], push_commits) end - def push_to_existing_branch?(ref, oldrev) + def push_to_existing_branch? # Return if this is not a push to a branch (e.g. new commits) - Gitlab::Git.branch_ref?(ref) && !Gitlab::Git.blank_ref?(oldrev) + Gitlab::Git.branch_ref?(params[:ref]) && !Gitlab::Git.blank_ref?(params[:oldrev]) end - def push_to_new_branch?(ref, oldrev) - Gitlab::Git.branch_ref?(ref) && Gitlab::Git.blank_ref?(oldrev) + def push_to_new_branch? + Gitlab::Git.branch_ref?(params[:ref]) && Gitlab::Git.blank_ref?(params[:oldrev]) end - def push_remove_branch?(ref, newrev) - Gitlab::Git.branch_ref?(ref) && Gitlab::Git.blank_ref?(newrev) + def push_remove_branch? + Gitlab::Git.branch_ref?(params[:ref]) && Gitlab::Git.blank_ref?(params[:newrev]) end - def push_to_branch?(ref) - Gitlab::Git.branch_ref?(ref) + def push_to_branch? + Gitlab::Git.branch_ref?(params[:ref]) end - def is_default_branch?(ref) - Gitlab::Git.branch_ref?(ref) && - (Gitlab::Git.ref_name(ref) == project.default_branch || project.default_branch.nil?) + def is_default_branch? + Gitlab::Git.branch_ref?(params[:ref]) && + (Gitlab::Git.ref_name(params[:ref]) == project.default_branch || project.default_branch.nil?) end def commit_user(commit) - commit.author || user + commit.author || current_user + end + + def branch_name + @branch_name ||= Gitlab::Git.ref_name(params[:ref]) end end diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb index 294157b4f0e..f4dcb142850 100644 --- a/app/services/projects/destroy_service.rb +++ b/app/services/projects/destroy_service.rb @@ -16,11 +16,15 @@ module Projects return false unless can?(current_user, :remove_project, project) project.team.truncate - project.repository.expire_cache unless project.empty_repo? repo_path = project.path_with_namespace 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.destroy! @@ -70,5 +74,13 @@ module Projects def removal_path(path) "#{path}+#{project.id}#{DELETED_FLAG}" 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 diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index 1083bcec054..edced010811 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -274,12 +274,15 @@ class SystemNoteService # Check if a cross reference to a noteable from a mentioner already exists # # This method is used to prevent multiple notes being created for a mention - # when a issue is updated, for example. + # when a issue is updated, for example. The method also calls notes_for_mentioner + # to check if the mentioner is a commit, and return matches only on commit hash + # instead of project + commit, to avoid repeated mentions from forks. # # noteable - Noteable object being referenced # mentioner - Mentionable object # # Returns Boolean + def self.cross_reference_exists?(noteable, mentioner) # Initial scope should be system notes of this noteable type notes = Note.system.where(noteable_type: noteable.class) @@ -291,14 +294,20 @@ class SystemNoteService notes = notes.where(noteable_id: noteable.id) end - gfm_reference = mentioner.gfm_reference(noteable.project) - notes = notes.where(note: cross_reference_note_content(gfm_reference)) - - notes.count > 0 + notes_for_mentioner(mentioner, noteable, notes).count > 0 end private + def self.notes_for_mentioner(mentioner, noteable, notes) + if mentioner.is_a?(Commit) + notes.where('note LIKE ?', "#{cross_reference_note_prefix}%#{mentioner.to_reference(nil)}") + else + gfm_reference = mentioner.gfm_reference(noteable.project) + notes.where(note: cross_reference_note_content(gfm_reference)) + end + end + def self.create_note(args = {}) Note.create(args.merge(system: true)) end |