summaryrefslogtreecommitdiff
path: root/app/models/concerns/repository_mirroring.rb
blob: f6aba91bc4cca2fe0c5a7110dccdeae80023d42f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
module RepositoryMirroring
  IMPORT_HEAD_REFS = '+refs/heads/*:refs/heads/*'.freeze
  IMPORT_TAG_REFS = '+refs/tags/*:refs/tags/*'.freeze

  def set_remote_as_mirror(name)
    # This is used to define repository as equivalent as "git clone --mirror"
    raw_repository.rugged.config["remote.#{name}.fetch"] = 'refs/*:refs/*'
    raw_repository.rugged.config["remote.#{name}.mirror"] = true
    raw_repository.rugged.config["remote.#{name}.prune"] = true
  end

  def set_import_remote_as_mirror(remote_name)
    # Add first fetch with Rugged so it does not create its own.
    raw_repository.rugged.config["remote.#{remote_name}.fetch"] = IMPORT_HEAD_REFS

    add_remote_fetch_config(remote_name, IMPORT_TAG_REFS)

    raw_repository.rugged.config["remote.#{remote_name}.mirror"] = true
    raw_repository.rugged.config["remote.#{remote_name}.prune"] = true
  end

  def add_remote_fetch_config(remote_name, refspec)
    run_git(%W[config --add remote.#{remote_name}.fetch #{refspec}])
  end

  def fetch_mirror(remote, url)
    add_remote(remote, url)
    set_remote_as_mirror(remote)
    fetch_remote(remote, forced: true)
    remove_remote(remote)
  end
end