2019-10-12 21:52:04 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
module ProjectForksHelper
|
|
|
|
def fork_project(project, user = nil, params = {})
|
2019-09-04 21:01:54 +05:30
|
|
|
Gitlab::GitalyClient.allow_n_plus_1_calls do
|
|
|
|
fork_project_direct(project, user, params)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def fork_project_direct(project, user = nil, params = {})
|
2018-03-17 18:26:18 +05:30
|
|
|
# Load the `fork_network` for the project to fork as there might be one that
|
|
|
|
# wasn't loaded yet.
|
|
|
|
project.reload unless project.fork_network
|
|
|
|
|
|
|
|
unless user
|
|
|
|
user = create(:user)
|
|
|
|
project.add_developer(user)
|
|
|
|
end
|
|
|
|
|
2020-11-24 15:15:51 +05:30
|
|
|
unless params[:namespace]
|
2018-03-17 18:26:18 +05:30
|
|
|
params[:namespace] = create(:group)
|
|
|
|
params[:namespace].add_owner(user)
|
|
|
|
end
|
|
|
|
|
2020-11-24 15:15:51 +05:30
|
|
|
namespace = params[:namespace]
|
|
|
|
create_repository = params.delete(:repository)
|
|
|
|
|
|
|
|
unless params[:target_project] || params[:using_service]
|
|
|
|
target_level = [project.visibility_level, namespace.visibility_level].min
|
|
|
|
visibility_level = Gitlab::VisibilityLevel.closest_allowed_level(target_level)
|
2021-12-11 22:18:48 +05:30
|
|
|
# Builds and MRs can't have higher visibility level than repository access level.
|
|
|
|
builds_access_level = [project.builds_access_level, project.repository_access_level].min
|
2020-11-24 15:15:51 +05:30
|
|
|
|
|
|
|
params[:target_project] =
|
|
|
|
create(:project,
|
|
|
|
(:repository if create_repository),
|
2021-12-11 22:18:48 +05:30
|
|
|
visibility_level: visibility_level,
|
|
|
|
builds_access_level: builds_access_level,
|
|
|
|
creator: user, namespace: namespace)
|
2020-11-24 15:15:51 +05:30
|
|
|
end
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
service = Projects::ForkService.new(project, user, params)
|
|
|
|
|
|
|
|
# Avoid creating a repository
|
|
|
|
unless create_repository
|
|
|
|
allow(RepositoryForkWorker).to receive(:perform_async).and_return(true)
|
|
|
|
shell = double('gitlab_shell', fork_repository: true)
|
|
|
|
allow(service).to receive(:gitlab_shell).and_return(shell)
|
|
|
|
end
|
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
forked_project = service.execute(params[:target_project])
|
2018-03-17 18:26:18 +05:30
|
|
|
|
|
|
|
# Reload the both projects so they know about their newly created fork_network
|
|
|
|
if forked_project.persisted?
|
|
|
|
project.reload
|
|
|
|
forked_project.reload
|
|
|
|
end
|
|
|
|
|
|
|
|
if create_repository
|
|
|
|
# The call to project.repository.after_import in RepositoryForkWorker does
|
|
|
|
# not reset the @exists variable of this forked_project.repository
|
2018-12-13 13:39:08 +05:30
|
|
|
# so we have to explicitly call this method to clear the @exists variable.
|
2018-03-17 18:26:18 +05:30
|
|
|
# of the instance we're returning here.
|
2019-12-04 20:38:33 +05:30
|
|
|
forked_project.repository.expire_content_cache
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
forked_project
|
|
|
|
end
|
|
|
|
|
|
|
|
def fork_project_with_submodules(project, user = nil, params = {})
|
2019-09-04 21:01:54 +05:30
|
|
|
Gitlab::GitalyClient.allow_n_plus_1_calls do
|
|
|
|
forked_project = fork_project_direct(project, user, params)
|
2022-08-13 15:12:31 +05:30
|
|
|
repo = Gitlab::GlRepository::PROJECT.repository_for(forked_project)
|
|
|
|
repo.create_from_bundle(TestEnv.forked_repo_bundle_path)
|
|
|
|
repo.expire_content_cache
|
2019-09-04 21:01:54 +05:30
|
|
|
|
|
|
|
forked_project
|
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
|
|
|
end
|