Class: Gitlab::GitalyClient::RepositoryService

Inherits:
Object
  • Object
show all
Includes:
EncodingHelper, WithFeatureFlagActors
Defined in:
lib/gitlab/gitaly_client/repository_service.rb

Constant Summary collapse

MAX_MSG_SIZE =
128.kilobytes

Constants included from EncodingHelper

EncodingHelper::BOM_UTF8, EncodingHelper::ENCODING_CONFIDENCE_THRESHOLD, EncodingHelper::ESCAPED_CHARS, EncodingHelper::UNICODE_REPLACEMENT_CHARACTER

Instance Attribute Summary

Attributes included from WithFeatureFlagActors

#repository_actor

Instance Method Summary collapse

Methods included from WithFeatureFlagActors

#gitaly_client_call, #gitaly_feature_flag_actors, #group_actor, #project_actor, #user_actor

Methods included from EncodingHelper

#binary_io, #detect_binary?, #detect_encoding, #detect_libgit2_binary?, #encode!, #encode_binary, #encode_utf8, #encode_utf8_no_detect, #encode_utf8_with_escaping!, #encode_utf8_with_replacement_character, #force_encode_utf8, #strip_bom, #unquote_path

Constructor Details

#initialize(repository) ⇒ RepositoryService

Returns a new instance of RepositoryService.



11
12
13
14
15
16
17
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 11

def initialize(repository)
  @repository = repository
  @gitaly_repo = repository.gitaly_repository
  @storage = repository.storage

  self.repository_actor = repository
end

Instance Method Details

#calculate_checksumObject



246
247
248
249
250
251
252
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 246

def calculate_checksum
  request  = Gitaly::CalculateChecksumRequest.new(repository: @gitaly_repo)
  response = gitaly_client_call(@storage, :repository_service, :calculate_checksum, request, timeout: GitalyClient.fast_timeout)
  response.checksum.presence
rescue GRPC::DataLoss => e
  raise Gitlab::Git::Repository::InvalidRepository, e
end

#create_bundle(save_path) ⇒ Object



211
212
213
214
215
216
217
218
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 211

def create_bundle(save_path)
  gitaly_fetch_stream_to_file(
    save_path,
    :create_bundle,
    Gitaly::CreateBundleRequest,
    GitalyClient.long_timeout
  )
end

#create_from_bundle(bundle_path) ⇒ Object



220
221
222
223
224
225
226
227
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 220

def create_from_bundle(bundle_path)
  gitaly_repo_stream_request(
    bundle_path,
    :create_repository_from_bundle,
    Gitaly::CreateRepositoryFromBundleRequest,
    GitalyClient.long_timeout
  )
end

#create_repository(default_branch = nil, object_format: nil) ⇒ Object

rubocop: enable Metrics/ParameterLists



121
122
123
124
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 121

def create_repository(default_branch = nil, object_format: nil)
  request = Gitaly::CreateRepositoryRequest.new(repository: @gitaly_repo, default_branch: encode_binary(default_branch), object_format: gitaly_object_format(object_format))
  gitaly_client_call(@storage, :repository_service, :create_repository, request, timeout: GitalyClient.fast_timeout)
end

#disconnect_alternatesObject



276
277
278
279
280
281
282
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 276

def disconnect_alternates
  request = Gitaly::DisconnectGitAlternatesRequest.new(
    repository: @gitaly_repo
  )

  gitaly_client_call(@storage, :object_pool_service, :disconnect_git_alternates, request, timeout: GitalyClient.long_timeout)
end

#exists?Boolean

Returns:

  • (Boolean)


19
20
21
22
23
24
25
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 19

def exists?
  request = Gitaly::RepositoryExistsRequest.new(repository: @gitaly_repo)

  response = gitaly_client_call(@storage, :repository_service, :repository_exists, request, timeout: GitalyClient.fast_timeout)

  response.exists
end

#fetch_remote(url, refmap:, ssh_auth:, forced:, no_tags:, timeout:, prune: true, http_authorization_header: "", resolved_address: "") ⇒ Object

rubocop: disable Metrics/ParameterLists The remote parameter is going away soonish anyway, at which point the Rubocop warning can be enabled again.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 92

def fetch_remote(url, refmap:, ssh_auth:, forced:, no_tags:, timeout:, prune: true, http_authorization_header: "", resolved_address: "")
  request = Gitaly::FetchRemoteRequest.new(
    repository: @gitaly_repo,
    force: forced,
    no_tags: no_tags,
    timeout: timeout,
    no_prune: !prune,
    remote_params: Gitaly::Remote.new(
      url: url,
      mirror_refmaps: Array.wrap(refmap).map(&:to_s),
      http_authorization_header: http_authorization_header,
      resolved_address: resolved_address
    )
  )

  if ssh_auth&.ssh_mirror_url?
    if ssh_auth.ssh_key_auth? && ssh_auth.ssh_private_key.present?
      request.ssh_key = ssh_auth.ssh_private_key
    end

    if ssh_auth.ssh_known_hosts.present?
      request.known_hosts = ssh_auth.ssh_known_hosts
    end
  end

  gitaly_client_call(@storage, :repository_service, :fetch_remote, request, timeout: GitalyClient.long_timeout)
end

#fetch_source_branch(source_repository, source_branch, local_ref) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 180

def fetch_source_branch(source_repository, source_branch, local_ref)
  request = Gitaly::FetchSourceBranchRequest.new(
    repository: @gitaly_repo,
    source_repository: source_repository.gitaly_repository,
    source_branch: source_branch.b,
    target_ref: local_ref.b
  )

  response = gitaly_client_call(
    @storage,
    :repository_service,
    :fetch_source_branch,
    request,
    timeout: GitalyClient.long_timeout,
    remote_storage: source_repository.storage
  )

  response.result
end

#find_licenseObject



240
241
242
243
244
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 240

def find_license
  request = Gitaly::FindLicenseRequest.new(repository: @gitaly_repo)

  gitaly_client_call(@storage, :repository_service, :find_license, request, timeout: GitalyClient.medium_timeout)
end

#find_merge_base(*revisions) ⇒ Object



133
134
135
136
137
138
139
140
141
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 133

def find_merge_base(*revisions)
  request = Gitaly::FindMergeBaseRequest.new(
    repository: @gitaly_repo,
    revisions: revisions.map { |r| encode_binary(r) }
  )

  response = gitaly_client_call(@storage, :repository_service, :find_merge_base, request, timeout: GitalyClient.fast_timeout)
  response.base.presence
end

#fork_repository(source_repository, branch = nil) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 143

def fork_repository(source_repository, branch = nil)
  revision = branch.present? ? "refs/heads/#{branch}" : ""

  request = Gitaly::CreateForkRequest.new(
    repository: @gitaly_repo,
    source_repository: source_repository.gitaly_repository,
    revision: revision
  )

  gitaly_client_call(
    @storage,
    :repository_service,
    :create_fork,
    request,
    remote_storage: source_repository.storage,
    timeout: GitalyClient.long_timeout
  )
end

#fsckObject



200
201
202
203
204
205
206
207
208
209
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 200

def fsck
  request = Gitaly::FsckRequest.new(repository: @gitaly_repo)
  response = gitaly_client_call(@storage, :repository_service, :fsck, request, timeout: GitalyClient.long_timeout)

  if response.error.empty?
    ["", 0]
  else
    [response.error.b, 1]
  end
end

#get_file_attributes(revision, paths, attributes) ⇒ Object



320
321
322
323
324
325
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 320

def get_file_attributes(revision, paths, attributes)
  request = Gitaly::GetFileAttributesRequest
    .new(repository: @gitaly_repo, revision: revision, paths: paths, attributes: attributes)

  gitaly_client_call(@repository.storage, :repository_service, :get_file_attributes, request, timeout: GitalyClient.fast_timeout)
end

#get_object_directory_sizeObject



61
62
63
64
65
66
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 61

def get_object_directory_size
  request = Gitaly::GetObjectDirectorySizeRequest.new(repository: @gitaly_repo)
  response = gitaly_client_call(@storage, :repository_service, :get_object_directory_size, request, timeout: GitalyClient.medium_timeout)

  response.size
end

#has_local_branches?Boolean

Returns:

  • (Boolean)


126
127
128
129
130
131
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 126

def has_local_branches?
  request = Gitaly::HasLocalBranchesRequest.new(repository: @gitaly_repo)
  response = gitaly_client_call(@storage, :repository_service, :has_local_branches, request, timeout: GitalyClient.fast_timeout)

  response.value
end

#import_repository(source, http_authorization_header: '', mirror: false, resolved_address: '') ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 162

def import_repository(source, http_authorization_header: '', mirror: false, resolved_address: '')
  request = Gitaly::CreateRepositoryFromURLRequest.new(
    repository: @gitaly_repo,
    url: source,
    http_authorization_header: http_authorization_header,
    mirror: mirror,
    resolved_address: resolved_address
  )

  gitaly_client_call(
    @storage,
    :repository_service,
    :create_repository_from_url,
    request,
    timeout: GitalyClient.long_timeout
  )
end

#info_attributesObject



80
81
82
83
84
85
86
87
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 80

def info_attributes
  request = Gitaly::GetInfoAttributesRequest.new(repository: @gitaly_repo)

  response = gitaly_client_call(@storage, :repository_service, :get_info_attributes, request, timeout: GitalyClient.fast_timeout)
  response.each_with_object([]) do |message, attributes|
    attributes << message.attributes
  end.join
end

#migrate_reference_backend(to_reftable: false) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 68

def migrate_reference_backend(to_reftable: false)
  target = if to_reftable
             Gitaly::MigrateReferenceBackendRequest::ReferenceBackend::REFERENCE_BACKEND_REFTABLE
           else
             Gitaly::MigrateReferenceBackendRequest::ReferenceBackend::REFERENCE_BACKEND_FILES
           end

  request = Gitaly::MigrateReferenceBackendRequest.new(repository: @gitaly_repo, target_reference_backend: target)

  gitaly_client_call(@storage, :repository_service, :migrate_reference_backend, request, timeout: GitalyClient.medium_timeout)
end

#object_formatObject



327
328
329
330
331
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 327

def object_format
  request = Gitaly::ObjectFormatRequest.new(repository: @gitaly_repo)

  gitaly_client_call(@storage, :repository_service, :object_format, request, timeout: GitalyClient.fast_timeout)
end

#object_poolObject



308
309
310
311
312
313
314
315
316
317
318
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 308

def object_pool
  request = Gitaly::GetObjectPoolRequest.new(repository: @gitaly_repo)

  gitaly_client_call(
    @storage,
    :object_pool_service,
    :get_object_pool,
    request,
    timeout: GitalyClient.medium_timeout
  )
end

#optimize_repository(eager: false) ⇒ Object

Optimize the repository. By default, this will perform heuristical housekeeping in the repository, which is the recommended approach and will only optimize what needs to be optimized. If ‘eager = true`, then Gitaly will instead be asked to perform eager housekeeping. As a consequence the housekeeping run will take a lot longer. It is not recommended to use eager housekeeping in general, but only in situations where it is explicitly required.



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 32

def optimize_repository(eager: false)
  strategy = if eager
               Gitaly::OptimizeRepositoryRequest::Strategy::STRATEGY_EAGER
             else
               Gitaly::OptimizeRepositoryRequest::Strategy::STRATEGY_HEURISTICAL
             end

  request = Gitaly::OptimizeRepositoryRequest.new(repository: @gitaly_repo,
    strategy: strategy)
  gitaly_client_call(@storage, :repository_service, :optimize_repository, request, timeout: GitalyClient.long_timeout)
end

#prune_unreachable_objectsObject



44
45
46
47
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 44

def prune_unreachable_objects
  request = Gitaly::PruneUnreachableObjectsRequest.new(repository: @gitaly_repo)
  gitaly_client_call(@storage, :repository_service, :prune_unreachable_objects, request, timeout: GitalyClient.long_timeout)
end

#raw_changes_between(from, to) ⇒ Object



254
255
256
257
258
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 254

def raw_changes_between(from, to)
  request = Gitaly::GetRawChangesRequest.new(repository: @gitaly_repo, from_revision: from, to_revision: to)

  gitaly_client_call(@storage, :repository_service, :get_raw_changes, request, timeout: GitalyClient.fast_timeout)
end

#removeObject



284
285
286
287
288
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 284

def remove
  request = Gitaly::RemoveRepositoryRequest.new(repository: @gitaly_repo)

  gitaly_client_call(@storage, :repository_service, :remove_repository, request, timeout: GitalyClient.long_timeout)
end

#replicate(source_repository, partition_hint: "") ⇒ Object



290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 290

def replicate(source_repository, partition_hint: "")
  request = Gitaly::ReplicateRepositoryRequest.new(
    repository: @gitaly_repo,
    source: source_repository.gitaly_repository
  )

  gitaly_client_call(
    @storage,
    :repository_service,
    :replicate_repository,
    request,
    remote_storage: source_repository.storage,
    timeout: GitalyClient.long_timeout
  ) do |kwargs|
    kwargs.deep_merge(metadata: { 'gitaly-partitioning-hint': partition_hint })
  end
end

#repository_infoObject



55
56
57
58
59
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 55

def repository_info
  request = Gitaly::RepositoryInfoRequest.new(repository: @gitaly_repo)

  gitaly_client_call(@storage, :repository_service, :repository_info, request, timeout: GitalyClient.long_timeout)
end

#repository_sizeObject



49
50
51
52
53
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 49

def repository_size
  request = Gitaly::RepositorySizeRequest.new(repository: @gitaly_repo)
  response = gitaly_client_call(@storage, :repository_service, :repository_size, request, timeout: GitalyClient.long_timeout)
  response.size
end

#search_files_by_content(ref, query, options = {}) ⇒ Object



265
266
267
268
269
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 265

def search_files_by_content(ref, query, options = {})
  request = Gitaly::SearchFilesByContentRequest.new(repository: @gitaly_repo, ref: encode_binary(ref), query: query)
  response = gitaly_client_call(@storage, :repository_service, :search_files_by_content, request, timeout: GitalyClient.default_timeout)
  search_results_from_response(response, options)
end

#search_files_by_name(ref, query, limit: 0, offset: 0) ⇒ Object



260
261
262
263
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 260

def search_files_by_name(ref, query, limit: 0, offset: 0)
  request = Gitaly::SearchFilesByNameRequest.new(repository: @gitaly_repo, ref: encode_binary(ref), query: query, limit: limit, offset: offset)
  gitaly_client_call(@storage, :repository_service, :search_files_by_name, request, timeout: GitalyClient.fast_timeout).flat_map(&:files)
end

#search_files_by_regexp(ref, filter, limit: 0, offset: 0) ⇒ Object



271
272
273
274
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 271

def search_files_by_regexp(ref, filter, limit: 0, offset: 0)
  request = Gitaly::SearchFilesByNameRequest.new(repository: @gitaly_repo, ref: encode_binary(ref), query: '.', filter: filter, limit: limit, offset: offset)
  gitaly_client_call(@storage, :repository_service, :search_files_by_name, request, timeout: GitalyClient.fast_timeout).flat_map(&:files)
end

#write_ref(ref_path, ref, old_ref) ⇒ Object



229
230
231
232
233
234
235
236
237
238
# File 'lib/gitlab/gitaly_client/repository_service.rb', line 229

def write_ref(ref_path, ref, old_ref)
  request = Gitaly::WriteRefRequest.new(
    repository: @gitaly_repo,
    ref: ref_path.b,
    revision: ref.b
  )
  request.old_revision = old_ref.b unless old_ref.nil?

  gitaly_client_call(@storage, :repository_service, :write_ref, request, timeout: GitalyClient.fast_timeout)
end