2013-03-19 11:37:50 -04:00
|
|
|
module Projects
|
2014-01-16 12:03:42 -05:00
|
|
|
class ForkService < BaseService
|
2013-03-19 11:37:50 -04:00
|
|
|
include Gitlab::ShellAdapter
|
|
|
|
|
|
|
|
def initialize(project, user)
|
|
|
|
@from_project, @current_user = project, user
|
|
|
|
end
|
|
|
|
|
|
|
|
def execute
|
2013-05-03 11:59:26 -04:00
|
|
|
project = @from_project.dup
|
2013-03-19 11:37:50 -04:00
|
|
|
project.name = @from_project.name
|
2013-05-02 15:30:13 -04:00
|
|
|
project.path = @from_project.path
|
2013-03-19 11:37:50 -04:00
|
|
|
project.namespace = current_user.namespace
|
2013-05-02 15:30:13 -04:00
|
|
|
project.creator = current_user
|
2013-03-19 11:37:50 -04:00
|
|
|
|
2013-05-02 15:30:13 -04:00
|
|
|
# If the project cannot save, we do not want to trigger the project destroy
|
|
|
|
# as this can have the side effect of deleting a repo attached to an existing
|
|
|
|
# project with the same name and namespace
|
|
|
|
if project.valid?
|
|
|
|
begin
|
|
|
|
Project.transaction do
|
|
|
|
#First save the DB entries as they can be rolled back if the repo fork fails
|
|
|
|
project.build_forked_project_link(forked_to_project_id: project.id, forked_from_project_id: @from_project.id)
|
|
|
|
if project.save
|
|
|
|
project.users_projects.create(project_access: UsersProject::MASTER, user: current_user)
|
|
|
|
end
|
|
|
|
#Now fork the repo
|
|
|
|
unless gitlab_shell.fork_repository(@from_project.path_with_namespace, project.namespace.path)
|
|
|
|
raise "forking failed in gitlab-shell"
|
|
|
|
end
|
|
|
|
project.ensure_satellite_exists
|
|
|
|
end
|
|
|
|
rescue => ex
|
|
|
|
project.errors.add(:base, "Fork transaction failed.")
|
|
|
|
project.destroy
|
2013-03-19 11:37:50 -04:00
|
|
|
end
|
2013-05-02 15:30:13 -04:00
|
|
|
else
|
|
|
|
project.errors.add(:base, "Invalid fork destination")
|
2013-03-19 11:37:50 -04:00
|
|
|
end
|
|
|
|
project
|
|
|
|
|
2013-05-02 15:30:13 -04:00
|
|
|
end
|
2013-03-19 11:37:50 -04:00
|
|
|
end
|
|
|
|
end
|