diff --git a/lib/gitlab/import_export/group_project_finder.rb b/lib/gitlab/import_export/group_project_finder.rb index 37923edb9db..be526ef55d5 100644 --- a/lib/gitlab/import_export/group_project_finder.rb +++ b/lib/gitlab/import_export/group_project_finder.rb @@ -14,7 +14,7 @@ module Gitlab end def initialize(klass, attributes) - @klass = klass + @klass = klass < Label ? Label : klass @attributes = attributes @group = @attributes[:group] @project = @attributes[:project] @@ -33,7 +33,7 @@ module Gitlab def where_clause return { project_id: @project.id } unless milestone? || label? - @attributes.slice(:title).map do |key, value| + @attributes.slice('title').map do |key, value| project_clause = table[key].eq(value).and(table[:project_id].eq(@project.id)) if @group @@ -51,9 +51,9 @@ module Gitlab def project_attributes @attributes.except(:group).tap do |atts| if label? - atts['type'] = 'ProjectLabel' + atts['type'] = 'ProjectLabel' # Always create project labels elsif milestone? - if atts['group_id'] + if atts['group_id'] # Transform new group milestones into project ones atts['iid'] = nil atts.delete('group_id') else @@ -64,13 +64,18 @@ module Gitlab end def label? - @klass == Label || @klass < Label + @klass == Label end def milestone? @klass == Milestone end + # If an existing group milesone used the IIID + # claim the IID back and set the group milestone to use one available + # This is neccessary to fix situations like the following: + # - Importing into a user namespace project with exported group milestones + # where the IID of the Group milestone could conflict with a project one. def claim_iid group_milestone = @project.milestones.find_by(iid: @attributes['iid']) diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index 992e3e708d5..5efebf867ad 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -80,7 +80,6 @@ module Gitlab case @relation_name when :merge_request_diff_files then setup_diff when :notes then setup_note - when *(EXISTING_OBJECT_CHECK - [:project_feature]) then setup_project_group when 'Ci::Pipeline' then setup_pipeline else @relation_hash['project_id'] = @project.id @@ -166,12 +165,6 @@ module Gitlab @relation_hash['target_project_id'] && @relation_hash['target_project_id'] == @relation_hash['source_project_id'] end - def setup_project_group - @relation_hash['project_id'] = @project.id - @relation_hash['group_id'] = @project.group&.id - @relation_hash.delete('type') - end - def reset_tokens! return unless Gitlab::ImportExport.reset_tokens? && TOKEN_RESET_MODELS.include?(@relation_name.to_s) @@ -266,27 +259,14 @@ module Gitlab end def find_or_create_object! - # Can't use IDs as validation exists calilng `.group` or `.project` + # Can't use IDs as validation exists calling `group` or `project` attributes finder_hash = parsed_relation_hash.tap do |hash| hash[:group] = @project.group if relation_class.attribute_method?('group_id') hash[:project] = @project - hash[:title] = parsed_relation_hash['title'] if parsed_relation_hash['title'] hash.delete('project_id') end - if label? - GroupProjectFinder.find_or_new(Label, finder_hash) - else - GroupProjectFinder.find_or_create(relation_class, finder_hash) - end - end - - def label? - @relation_name.to_s.include?('label') - end - - def milestone? - @relation_name.to_s.include?('milestone') + GroupProjectFinder.find_or_create(relation_class, finder_hash) end end end diff --git a/spec/lib/gitlab/import_export/project.light.json b/spec/lib/gitlab/import_export/project.light.json index a401ce4c0c7..ba2248073f5 100644 --- a/spec/lib/gitlab/import_export/project.light.json +++ b/spec/lib/gitlab/import_export/project.light.json @@ -67,7 +67,7 @@ "milestone": { "id": 1, "title": "A milestone", - "project_id": 8, + "group_id": 8, "description": "Project-level milestone", "due_date": null, "created_at": "2016-06-14T15:02:04.415Z",