Class: Gitlab::Git::Repository

Inherits:
Object
  • Object
show all
Includes:
Popen
Defined in:
lib/gitlab_git/repository.rb

Defined Under Namespace

Classes: NoRepository

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Popen

#popen

Constructor Details

#initialize(path_with_namespace, root_ref = 'master') ⇒ Repository

Returns a new instance of Repository.



31
32
33
34
35
36
37
# File 'lib/gitlab_git/repository.rb', line 31

def initialize(path_with_namespace, root_ref = 'master')
  @root_ref = root_ref || "master"
  @path_with_namespace = path_with_namespace

  # Init grit repo object
  raw
end

Class Attribute Details

.repos_pathObject

Returns the value of attribute repos_path.



12
13
14
# File 'lib/gitlab_git/repository.rb', line 12

def repos_path
  @repos_path
end

Instance Attribute Details

#path_with_namespaceObject

Repository directory name with namespace direcotry Examples:

gitlab/gitolite
diaspora


20
21
22
# File 'lib/gitlab_git/repository.rb', line 20

def path_with_namespace
  @path_with_namespace
end

#rawObject (readonly)

Grit repo object



26
27
28
# File 'lib/gitlab_git/repository.rb', line 26

def raw
  @raw
end

#root_refObject

Default branch in the repository



23
24
25
# File 'lib/gitlab_git/repository.rb', line 23

def root_ref
  @root_ref
end

Instance Method Details

#archive_repo(ref, storage_path) ⇒ Object

Archive Project to .tar.gz

Already packed repo archives stored at app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/gitlab_git/repository.rb', line 120

def archive_repo(ref, storage_path)
  ref = ref || self.root_ref
  commit = Gitlab::Git::Commit.find(self, ref)
  return nil unless commit

  # Build file path
  file_name = self.path_with_namespace.gsub("/","_") + "-" + commit.id.to_s + ".tar.gz"
  file_path = File.join(storage_path, self.path_with_namespace, file_name)

  # Put files into a directory before archiving
  prefix = File.basename(self.path_with_namespace) + "/"

  # Create file if not exists
  unless File.exists?(file_path)
    FileUtils.mkdir_p File.dirname(file_path)
    file = self.raw.archive_to_file(ref, prefix,  file_path)
  end

  file_path
end

#branch_namesObject

Returns an Array of branch names sorted by name ASC



55
56
57
# File 'lib/gitlab_git/repository.rb', line 55

def branch_names
  branches.map(&:name)
end

#branch_names_contains(commit) ⇒ Object

Returns branch names collection that contains the special commit(SHA1 or name)

Ex.

repo.branch_names_contains('master')


270
271
272
273
274
275
276
277
# File 'lib/gitlab_git/repository.rb', line 270

def branch_names_contains(commit)
  output = raw.git.native(:branch, {contains: true}, commit)
  # The output is expected as follow
  #   fix-aaa
  #   fix-bbb
  # * master
  output.scan(/[^* \n]+/)
end

#branchesObject

Returns an Array of Branches



60
61
62
# File 'lib/gitlab_git/repository.rb', line 60

def branches
  raw.branches.sort_by(&:name)
end

#commits_between(from, to) ⇒ Object

Delegate commits_between to Grit method



191
192
193
# File 'lib/gitlab_git/repository.rb', line 191

def commits_between(from, to)
  raw.commits_between(from, to)
end

#diff(from, to) ⇒ Object



199
200
201
# File 'lib/gitlab_git/repository.rb', line 199

def diff(from, to)
  raw.diff(from, to)
end

#discover_default_branchObject

Discovers the default branch based on the repository’s available branches

  • If no branches are present, returns nil

  • If one branch is present, returns its name

  • If two or more branches are present, returns the one that has a name matching root_ref (default_branch or ‘master’ if default_branch is nil)



105
106
107
108
109
110
111
112
113
# File 'lib/gitlab_git/repository.rb', line 105

def discover_default_branch
  if branch_names.length == 0
    nil
  elsif branch_names.length == 1
    branch_names.first
  else
    branch_names.select { |v| v == root_ref }.first
  end
end

#empty?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/gitlab_git/repository.rb', line 95

def empty?
  !has_commits?
end

#find_commits(options = {}) ⇒ Object

Returns commits collection

Ex.

repo.find_commits(
  ref: 'master',
  max_count: 10,
  skip: 5,
  order: :date
)

+options+ is a Hash of optional arguments to git
  :ref is the ref from which to begin (SHA1 or name)
  :contains is the commit contained by the refs from which to begin (SHA1 or name)
  :max_count is the maximum number of commits to fetch
  :skip is the number of commits to skip
  :order is the commits order and allowed value is :date(default) or :topo


220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/gitlab_git/repository.rb', line 220

def find_commits(options = {})
  actual_options = options.dup

  allowed_options = [:ref, :max_count, :skip, :contains, :order]

  actual_options.keep_if do |key, value|
    allowed_options.include?(key)
  end

  default_options = {pretty: 'raw', order: :date}

  actual_options = default_options.merge(actual_options)

  order = actual_options.delete(:order)

  case order
  when :date
    actual_options[:date_order] = true
  when :topo
    actual_options[:topo_order] = true
  end

  ref = actual_options.delete(:ref)

  containing_commit = actual_options.delete(:contains)

  args = []

  if ref
    args.push(ref)
  elsif containing_commit
    args.push(*branch_names_contains(containing_commit))
  else
    actual_options[:all] = true
  end

  output = raw.git.native(:rev_list, actual_options, *args)

  Grit::Commit.list_from_string(raw, output).map do |commit|
    Gitlab::Git::Commit.decorate(commit)
  end
rescue Grit::GitRuby::Repository::NoSuchShaFound
  []
end

#has_commits?Boolean

Returns:

  • (Boolean)


89
90
91
92
93
# File 'lib/gitlab_git/repository.rb', line 89

def has_commits?
  !!Gitlab::Git::Commit.last(self)
rescue Grit::NoSuchPathError
  false
end

#headsObject



79
80
81
# File 'lib/gitlab_git/repository.rb', line 79

def heads
  @heads ||= raw.heads.sort_by(&:name)
end

#log(options) ⇒ Object

Delegate log to Grit method

Usage.

repo.log(
  ref: 'master',
  path: 'app/models',
  limit: 10,
  offset: 5,
)


169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/gitlab_git/repository.rb', line 169

def log(options)
  default_options = {
    limit: 10,
    offset: 0,
    path: nil,
    ref: root_ref,
    follow: false
  }

  options = default_options.merge(options)

  raw.log(
    options[:ref] || root_ref,
    options[:path],
    max_count: options[:limit].to_i,
    skip: options[:offset].to_i,
    follow: options[:follow]
  )
end

#merge_base_commit(from, to) ⇒ Object



195
196
197
# File 'lib/gitlab_git/repository.rb', line 195

def merge_base_commit(from, to)
  raw.git.native(:merge_base, {}, [to, from]).strip
end

#path_to_repoObject



39
40
41
# File 'lib/gitlab_git/repository.rb', line 39

def path_to_repo
  @path_to_repo ||= File.join(repos_path, "#{path_with_namespace}.git")
end

#ref_namesObject

Returns an Array of branch and tag names



75
76
77
# File 'lib/gitlab_git/repository.rb', line 75

def ref_names
  branch_names + tag_names
end

#refs_hashObject

Get refs hash which key is SHA1 and value is ref object(Grit::Head or Grit::Remote or Grit::Tag)



280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/gitlab_git/repository.rb', line 280

def refs_hash
  # Initialize only when first call
  if @refs_hash.nil?
    @refs_hash = Hash.new { |h, k| h[k] = [] }

    @raw.refs.each do |r|
      @refs_hash[r.commit.id] << r
    end
  end

  @refs_hash
end

#repoObject

Grit repo object compatibility



29
30
31
# File 'lib/gitlab_git/repository.rb', line 29

def raw
  @raw
end

#repos_pathObject



43
44
45
# File 'lib/gitlab_git/repository.rb', line 43

def repos_path
  self.class.repos_path
end

#search_files(query, ref = nil) ⇒ Object



147
148
149
150
151
152
153
154
155
156
157
# File 'lib/gitlab_git/repository.rb', line 147

def search_files(query, ref = nil)
  if ref.nil? || ref == ""
    ref = root_ref
  end

  greps = raw.grep(query, 3, ref)

  greps.map do |grep|
    Gitlab::Git::BlobSnippet.new(ref, grep.content, grep.startline, grep.filename)
  end
end

#sizeObject

Return repo size in megabytes



142
143
144
145
# File 'lib/gitlab_git/repository.rb', line 142

def size
  size = popen('du -s', path_to_repo).first.strip.to_i
  (size.to_f / 1024).round(2)
end

#tag_namesObject

Returns an Array of tag names



65
66
67
# File 'lib/gitlab_git/repository.rb', line 65

def tag_names
  tags.map(&:name)
end

#tagsObject

Returns an Array of Tags



70
71
72
# File 'lib/gitlab_git/repository.rb', line 70

def tags
  raw.tags.sort_by(&:name).reverse
end

#tree(fcommit, path = nil) ⇒ Object



83
84
85
86
87
# File 'lib/gitlab_git/repository.rb', line 83

def tree(fcommit, path = nil)
  fcommit = commit if fcommit == :head
  tree = fcommit.tree
  path ? (tree / path) : tree
end