diff options
Diffstat (limited to 'app/services/git')
-rw-r--r-- | app/services/git/base_hooks_service.rb | 64 | ||||
-rw-r--r-- | app/services/git/branch_hooks_service.rb | 29 |
2 files changed, 69 insertions, 24 deletions
diff --git a/app/services/git/base_hooks_service.rb b/app/services/git/base_hooks_service.rb index d30df34e54b..47c308c8280 100644 --- a/app/services/git/base_hooks_service.rb +++ b/app/services/git/base_hooks_service.rb @@ -8,8 +8,6 @@ module Git PROCESS_COMMIT_LIMIT = 100 def execute - project.repository.after_create if project.empty_repo? - create_events create_pipelines execute_project_hooks @@ -19,7 +17,7 @@ module Git update_remote_mirrors - push_data + success end private @@ -33,7 +31,7 @@ module Git end def limited_commits - commits.last(PROCESS_COMMIT_LIMIT) + @limited_commits ||= commits.last(PROCESS_COMMIT_LIMIT) end def commits_count @@ -48,43 +46,69 @@ module Git [] end + # Push events in the activity feed only show information for the + # last commit. def create_events - EventCreateService.new.push(project, current_user, push_data) + EventCreateService.new.push(project, current_user, event_push_data) end def create_pipelines return unless params.fetch(:create_pipelines, true) Ci::CreatePipelineService - .new(project, current_user, push_data) + .new(project, current_user, pipeline_params) .execute(:push, pipeline_options) end def execute_project_hooks - project.execute_hooks(push_data, hook_name) - project.execute_services(push_data, hook_name) + # Creating push_data invokes one CommitDelta RPC per commit. Only + # build this data if we actually need it. + project.execute_hooks(push_data, hook_name) if project.has_active_hooks?(hook_name) + project.execute_services(push_data, hook_name) if project.has_active_services?(hook_name) end def enqueue_invalidate_cache - ProjectCacheWorker.perform_async( - project.id, - invalidated_file_types, - [:commit_count, :repository_size] - ) + file_types = invalidated_file_types + + return unless file_types.present? + + ProjectCacheWorker.perform_async(project.id, file_types, [], false) end - def push_data - @push_data ||= Gitlab::DataBuilder::Push.build( - project: project, - user: current_user, + def pipeline_params + { + before: params[:oldrev], + after: params[:newrev], + ref: params[:ref], + push_options: params[:push_options] || {}, + checkout_sha: Gitlab::DataBuilder::Push.checkout_sha( + project.repository, params[:newrev], params[:ref]) + } + end + + def push_data_params(commits:, with_changed_files: true) + { oldrev: params[:oldrev], newrev: params[:newrev], ref: params[:ref], - commits: limited_commits, + project: project, + user: current_user, + commits: commits, message: event_message, commits_count: commits_count, - push_options: params[:push_options] || {} - ) + with_changed_files: with_changed_files + } + end + + def event_push_data + # We only need the last commit for the event push, and we don't + # need the full deltas either. + @event_push_data ||= Gitlab::DataBuilder::Push.build( + push_data_params(commits: commits.last, with_changed_files: false)) + end + + def push_data + @push_data ||= Gitlab::DataBuilder::Push.build(push_data_params(commits: limited_commits)) # Dependent code may modify the push data, so return a duplicate each time @push_data.dup diff --git a/app/services/git/branch_hooks_service.rb b/app/services/git/branch_hooks_service.rb index c41f445c3c4..d2b037a680c 100644 --- a/app/services/git/branch_hooks_service.rb +++ b/app/services/git/branch_hooks_service.rb @@ -63,7 +63,7 @@ module Git end def branch_create_hooks - project.repository.after_create_branch + project.repository.after_create_branch(expire_cache: false) project.after_create_default_branch if default_branch? end @@ -78,13 +78,21 @@ module Git end def branch_remove_hooks - project.repository.after_remove_branch + project.repository.after_remove_branch(expire_cache: false) end # Schedules processing of commit messages def enqueue_process_commit_messages - limited_commits.each do |commit| - next unless commit.matches_cross_reference_regex? + referencing_commits = limited_commits.select(&:matches_cross_reference_regex?) + + upstream_commit_ids = upstream_commit_ids(referencing_commits) + + referencing_commits.each do |commit| + # Avoid reprocessing commits that already exist upstream if the project + # is a fork. This will prevent duplicated/superfluous system notes on + # mentionables referenced by a commit that is pushed to the upstream, + # that is then also pushed to forks when these get synced by users. + next if upstream_commit_ids.include?(commit.id) ProcessCommitWorker.perform_async( project.id, @@ -142,5 +150,18 @@ module Git def branch_name strong_memoize(:branch_name) { Gitlab::Git.ref_name(params[:ref]) } end + + def upstream_commit_ids(commits) + set = Set.new + + upstream_project = project.fork_source + if upstream_project + upstream_project + .commits_by(oids: commits.map(&:id)) + .each { |commit| set << commit.id } + end + + set + end end end |