diff --git a/ee/app/models/ee/project.rb b/ee/app/models/ee/project.rb index e3f12e99e9463aa48355b4c678c5b426c50d818b..741e9f3b1378af65d2bfda347b5bab09576fec3a 100644 --- a/ee/app/models/ee/project.rb +++ b/ee/app/models/ee/project.rb @@ -690,7 +690,7 @@ def mirror_with_content? mirror? && !empty_repo? end - def fetch_mirror(forced: false, check_tags_changed: false) + def fetch_mirror(forced: false, check_tags_changed: false, check_repo_changed: false) return unless mirror? # Only send the password if it's needed @@ -701,7 +701,7 @@ def fetch_mirror(forced: false, check_tags_changed: false) username_only_import_url end - repository.fetch_upstream(url, forced: forced, check_tags_changed: check_tags_changed) + repository.fetch_upstream(url, forced: forced, check_tags_changed: check_tags_changed, check_repo_changed: check_repo_changed) end def can_override_approvers? diff --git a/ee/app/models/ee/repository.rb b/ee/app/models/ee/repository.rb index 3e12819556f10629f7d7c58d15f8b0defa2a3240..7fe5aab561447b0a57640ae242368a907905cf4b 100644 --- a/ee/app/models/ee/repository.rb +++ b/ee/app/models/ee/repository.rb @@ -25,13 +25,14 @@ def after_sync expire_content_cache end - def fetch_upstream(url, forced: false, check_tags_changed: false) + def fetch_upstream(url, forced: false, check_tags_changed: false, check_repo_changed: false) fetch_remote( url, refmap: ["+refs/heads/*:refs/remotes/#{MIRROR_REMOTE}/*"], ssh_auth: project&.import_data, forced: forced, - check_tags_changed: check_tags_changed + check_tags_changed: check_tags_changed, + check_repo_changed: check_repo_changed ) end diff --git a/ee/app/services/projects/update_mirror_service.rb b/ee/app/services/projects/update_mirror_service.rb index 291b2488cfc07a006a253030348dbfb97b567f63..48b27e092cde2179dc53521da53321cbb32de71e 100644 --- a/ee/app/services/projects/update_mirror_service.rb +++ b/ee/app/services/projects/update_mirror_service.rb @@ -26,17 +26,15 @@ def execute return error("The mirror user is not allowed to push code to all branches on this project.") end - checksum_before = project.repository.checksum - - update_tags do - project.fetch_mirror(forced: true, check_tags_changed: true) + fetch_result = update_tags do + project.fetch_mirror(forced: true, check_tags_changed: true, check_repo_changed: true) end - update_branches + # Rails.logger.error("ASH: UpdateMirrorService#execute: fetch_result=[#{fetch_result}]") - # Updating LFS objects is expensive since it requires scanning for blobs with pointers. - # Let's skip this if the repository hasn't changed. - update_lfs_objects if update_lfs_objects?(checksum_before) + update_lfs_objects if update_lfs_objects?(fetch_result.repo_changed) + + update_branches # Running git fetch in the repository creates loose objects in the same # way running git push *to* the repository does, so ensure we run regular @@ -50,8 +48,8 @@ def execute private - def update_lfs_objects?(checksum) - project.lfs_enabled? && project.repository.checksum != checksum + def update_lfs_objects?(repo_changed) + repo_changed && project.lfs_enabled? end def import_url_invalid? diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index b0843af27f868ad88de3f5a497700c7eab2576b5..3e7183d5c875939dfaef40658a36518c2e600f81 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -905,7 +905,7 @@ def empty? def fetch_remote( # rubocop:disable Metrics/ParameterLists url, refmap: nil, ssh_auth: nil, forced: false, no_tags: false, prune: true, - check_tags_changed: false, http_authorization_header: "", resolved_address: "") + check_tags_changed: false, check_repo_changed: false, http_authorization_header: "", resolved_address: "") wrapped_gitaly_errors do gitaly_repository_client.fetch_remote( url, @@ -915,6 +915,7 @@ def fetch_remote( # rubocop:disable Metrics/ParameterLists no_tags: no_tags, prune: prune, check_tags_changed: check_tags_changed, + check_repo_changed: check_repo_changed, timeout: GITLAB_PROJECTS_TIMEOUT, http_authorization_header: http_authorization_header, resolved_address: resolved_address diff --git a/lib/gitlab/gitaly_client/repository_service.rb b/lib/gitlab/gitaly_client/repository_service.rb index 0725ef371a881f6fc688c261489e9dc77ffdbde1..b757303ab6dbdc3eceaec4bb6014c4d9062c9e59 100644 --- a/lib/gitlab/gitaly_client/repository_service.rb +++ b/lib/gitlab/gitaly_client/repository_service.rb @@ -77,7 +77,7 @@ def info_attributes # rubocop: disable Metrics/ParameterLists # The `remote` parameter is going away soonish anyway, at which point the # Rubocop warning can be enabled again. - def fetch_remote(url, refmap:, ssh_auth:, forced:, no_tags:, timeout:, prune: true, check_tags_changed: false, http_authorization_header: "", resolved_address: "") + def fetch_remote(url, refmap:, ssh_auth:, forced:, no_tags:, timeout:, prune: true, check_tags_changed: false, check_repo_changed: false, http_authorization_header: "", resolved_address: "") request = Gitaly::FetchRemoteRequest.new( repository: @gitaly_repo, force: forced, @@ -85,6 +85,7 @@ def fetch_remote(url, refmap:, ssh_auth:, forced:, no_tags:, timeout:, prune: tr timeout: timeout, no_prune: !prune, check_tags_changed: check_tags_changed, + check_repo_changed: check_repo_changed, remote_params: Gitaly::Remote.new( url: url, mirror_refmaps: Array.wrap(refmap).map(&:to_s),