Read about our upcoming Code of Conduct on this issue

This instance will be upgraded to Heptapod 0.28.1 on 2022-01-26 at 16:00 UTC+1 (a few minutes of down time)

fork_service.rb 1.94 KB
Newer Older
1
module Projects
2
  class ForkService < BaseService
3
4
5
    include Gitlab::ShellAdapter

    def execute
6
7
      @from_project = @project

8
9
10
11
12
13
      project_params = {
        visibility_level: @from_project.visibility_level,
        description: @from_project.description,
      }

      project = Project.new(project_params)
14
      project.name = @from_project.name
15
      project.path = @from_project.path
16
      project.creator = @current_user
17
      if @from_project.avatar.present? && @from_project.avatar.image?
18
19
        project.avatar = @from_project.avatar
      end
20

21
22
      if namespace = @params[:namespace]
        project.namespace = namespace
23
24
      else
        project.namespace = @current_user.namespace
25
      end
26

27
28
29
30
      unless @current_user.can?(:create_projects, project.namespace)
        project.errors.add(:namespace, 'insufficient access rights')
        return project
      end
31

32
33
34
35
36
37
38
39
40
      # 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
41
              project.team << [@current_user, :master]
42
43
44
            end
            #Now fork the repo
            unless gitlab_shell.fork_repository(@from_project.path_with_namespace, project.namespace.path)
45
              raise 'forking failed in gitlab-shell'
46
47
48
49
            end
            project.ensure_satellite_exists
          end
        rescue => ex
50
          project.errors.add(:base, 'Fork transaction failed.')
51
          project.destroy
52
        end
53
      else
54
        project.errors.add(:base, 'Invalid fork destination')
55
56
      end

57
      project
58
    end
59
60
  end
end