diff options
author | Douwe Maan <douwe@gitlab.com> | 2017-10-07 10:56:24 +0000 |
---|---|---|
committer | Douwe Maan <douwe@gitlab.com> | 2017-10-07 10:56:24 +0000 |
commit | 3cb798357fbfb8b3230b60130fc1c6b328ae84b7 (patch) | |
tree | ed86ce7199537e12a3ddf9ab71a2832b3da28621 /app/models | |
parent | 8eec69ef41ed66c2ef3c5db73f97eb39a9458f72 (diff) | |
parent | fc51bde939a24347e21b765b8c0e4238e2ffc67d (diff) | |
download | gitlab-ce-3cb798357fbfb8b3230b60130fc1c6b328ae84b7.tar.gz |
Merge branch 'bvl-fork-network-schema' into 'master'
Create merge requests across a fork network
Closes #20097
See merge request gitlab-org/gitlab-ce!14422
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/fork_network.rb | 15 | ||||
-rw-r--r-- | app/models/fork_network_member.rb | 7 | ||||
-rw-r--r-- | app/models/merge_request.rb | 2 | ||||
-rw-r--r-- | app/models/namespace.rb | 4 | ||||
-rw-r--r-- | app/models/project.rb | 29 | ||||
-rw-r--r-- | app/models/user.rb | 10 |
6 files changed, 54 insertions, 13 deletions
diff --git a/app/models/fork_network.rb b/app/models/fork_network.rb new file mode 100644 index 00000000000..218e37a5312 --- /dev/null +++ b/app/models/fork_network.rb @@ -0,0 +1,15 @@ +class ForkNetwork < ActiveRecord::Base + belongs_to :root_project, class_name: 'Project' + has_many :fork_network_members + has_many :projects, through: :fork_network_members + + after_create :add_root_as_member, if: :root_project + + def add_root_as_member + projects << root_project + end + + def find_forks_in(other_projects) + projects.where(id: other_projects) + end +end diff --git a/app/models/fork_network_member.rb b/app/models/fork_network_member.rb new file mode 100644 index 00000000000..6a9b52a1ef8 --- /dev/null +++ b/app/models/fork_network_member.rb @@ -0,0 +1,7 @@ +class ForkNetworkMember < ActiveRecord::Base + belongs_to :fork_network + belongs_to :project + belongs_to :forked_from_project, class_name: 'Project' + + validates :fork_network, :project, presence: true +end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 086226618e6..9b312f7db6c 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -403,7 +403,7 @@ class MergeRequest < ActiveRecord::Base return false unless for_fork? return true unless source_project - !source_project.forked_from?(target_project) + !source_project.in_fork_network_of?(target_project) end def reopenable? diff --git a/app/models/namespace.rb b/app/models/namespace.rb index e279d8dd8c5..4672881e220 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -139,7 +139,9 @@ class Namespace < ActiveRecord::Base end def find_fork_of(project) - projects.joins(:forked_project_link).find_by('forked_project_links.forked_from_project_id = ?', project.id) + return nil unless project.fork_network + + project.fork_network.find_forks_in(projects).first end def lfs_enabled? diff --git a/app/models/project.rb b/app/models/project.rb index 608b545f99f..ad1c339ae78 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -118,11 +118,20 @@ class Project < ActiveRecord::Base has_one :mock_monitoring_service has_one :microsoft_teams_service + # TODO: replace these relations with the fork network versions has_one :forked_project_link, foreign_key: "forked_to_project_id" has_one :forked_from_project, through: :forked_project_link has_many :forked_project_links, foreign_key: "forked_from_project_id" has_many :forks, through: :forked_project_links, source: :forked_to_project + # TODO: replace these relations with the fork network versions + + has_one :root_of_fork_network, + foreign_key: 'root_project_id', + inverse_of: :root_project, + class_name: 'ForkNetwork' + has_one :fork_network_member + has_one :fork_network, through: :fork_network_member # Merge Requests for target project should be removed with it has_many :merge_requests, foreign_key: 'target_project_id' @@ -1000,6 +1009,11 @@ class Project < ActiveRecord::Base end def forked? + return true if fork_network && fork_network.root_project != self + + # TODO: Use only the above conditional using the `fork_network` + # This is the old conditional that looks at the `forked_project_link`, we + # fall back to this while we're migrating the new models !(forked_project_link.nil? || forked_project_link.forked_from_project.nil?) end @@ -1119,8 +1133,19 @@ class Project < ActiveRecord::Base end end - def forked_from?(project) - forked? && project == forked_from_project + def forked_from?(other_project) + forked? && forked_from_project == other_project + end + + def in_fork_network_of?(other_project) + # TODO: Remove this in a next release when all fork_networks are populated + # This makes sure all MergeRequests remain valid while the projects don't + # have a fork_network yet. + return true if forked_from?(other_project) + + return false if fork_network.nil? || other_project.fork_network.nil? + + fork_network == other_project.fork_network end def origin_merge_requests diff --git a/app/models/user.rb b/app/models/user.rb index 959738ba608..c3f115ca074 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -697,15 +697,7 @@ class User < ActiveRecord::Base end def fork_of(project) - links = ForkedProjectLink.where( - forked_from_project_id: project, - forked_to_project_id: personal_projects.unscope(:order) - ) - if links.any? - links.first.forked_to_project - else - nil - end + namespace.find_fork_of(project) end def ldap_user? |