gitlab_git 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/gitlab_git/blame.rb +23 -0
- data/lib/gitlab_git/blob.rb +44 -0
- data/lib/gitlab_git/commit.rb +140 -0
- data/lib/gitlab_git/compare.rb +35 -0
- data/lib/gitlab_git/diff.rb +63 -0
- data/lib/gitlab_git/popen.rb +20 -0
- data/lib/gitlab_git/repository.rb +225 -0
- data/lib/gitlab_git/stats.rb +75 -0
- data/lib/gitlab_git/tree.rb +52 -0
- metadata +10 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c8f85ff5ac6e3846697e0a4e5c479cd608bffdd
|
4
|
+
data.tar.gz: 29c128efbfffb375d443274f6c49b3641443321e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab12c3ab17f22500f9483f4cabbd01aa94f098b11990373399df73676e9756c809f1af6ce957e8608d5e0286bf2d69c6ef3db613d5b92698215e997bd40a3376
|
7
|
+
data.tar.gz: 5bb1ab43d66022fce5d2c20eda9b17270a0f0d0ddea1f600771c583054c78b1a05258d140edcb36515597f9b8e82c03e766ef8e3c22fa53bff91c168ea5d66b0
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Gitlab
|
2
|
+
module Git
|
3
|
+
class Blame
|
4
|
+
|
5
|
+
attr_accessor :repository, :sha, :path
|
6
|
+
|
7
|
+
def initialize(repository, sha, path)
|
8
|
+
@repository, @sha, @path = repository, sha, path
|
9
|
+
end
|
10
|
+
|
11
|
+
def each
|
12
|
+
raw_blame = Grit::Blob.blame(repository.repo, sha, path)
|
13
|
+
|
14
|
+
raw_blame.each do |commit, lines|
|
15
|
+
next unless commit
|
16
|
+
|
17
|
+
commit = Gitlab::Git::Commit.new(commit)
|
18
|
+
yield(commit, lines)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Gitlab
|
2
|
+
module Git
|
3
|
+
class Blob
|
4
|
+
include Linguist::BlobHelper
|
5
|
+
|
6
|
+
attr_accessor :raw_blob
|
7
|
+
|
8
|
+
def initialize(repository, sha, ref, path)
|
9
|
+
@repository, @sha, @ref = repository, sha, ref
|
10
|
+
|
11
|
+
@commit = @repository.commit(sha)
|
12
|
+
@raw_blob = @repository.tree(@commit, path)
|
13
|
+
end
|
14
|
+
|
15
|
+
def data
|
16
|
+
if raw_blob
|
17
|
+
raw_blob.data
|
18
|
+
else
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def name
|
24
|
+
raw_blob.name
|
25
|
+
end
|
26
|
+
|
27
|
+
def exists?
|
28
|
+
raw_blob
|
29
|
+
end
|
30
|
+
|
31
|
+
def empty?
|
32
|
+
!data || data == ''
|
33
|
+
end
|
34
|
+
|
35
|
+
def mode
|
36
|
+
raw_blob.mode
|
37
|
+
end
|
38
|
+
|
39
|
+
def size
|
40
|
+
raw_blob.size
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# Gitlab::Git::Commit is a wrapper around native Grit::Commit object
|
2
|
+
# We dont want to use grit objects inside app/
|
3
|
+
# It helps us easily migrate to rugged in future
|
4
|
+
module Gitlab
|
5
|
+
module Git
|
6
|
+
class Commit
|
7
|
+
attr_accessor :raw_commit, :head, :refs,
|
8
|
+
:id, :authored_date, :committed_date, :message,
|
9
|
+
:author_name, :author_email, :parent_ids,
|
10
|
+
:committer_name, :committer_email
|
11
|
+
|
12
|
+
def initialize(raw_commit, head = nil)
|
13
|
+
raise "Nil as raw commit passed" unless raw_commit
|
14
|
+
|
15
|
+
if raw_commit.is_a?(Hash)
|
16
|
+
init_from_hash(raw_commit)
|
17
|
+
else
|
18
|
+
init_from_grit(raw_commit)
|
19
|
+
end
|
20
|
+
|
21
|
+
@head = head
|
22
|
+
end
|
23
|
+
|
24
|
+
def serialize_keys
|
25
|
+
@serialize_keys ||= %w(id authored_date committed_date author_name author_email committer_name committer_email message parent_ids).map(&:to_sym)
|
26
|
+
end
|
27
|
+
|
28
|
+
def sha
|
29
|
+
id
|
30
|
+
end
|
31
|
+
|
32
|
+
def short_id(length = 10)
|
33
|
+
id.to_s[0..length]
|
34
|
+
end
|
35
|
+
|
36
|
+
def safe_message
|
37
|
+
@safe_message ||= message
|
38
|
+
end
|
39
|
+
|
40
|
+
def created_at
|
41
|
+
committed_date
|
42
|
+
end
|
43
|
+
|
44
|
+
# Was this commit committed by a different person than the original author?
|
45
|
+
def different_committer?
|
46
|
+
author_name != committer_name || author_email != committer_email
|
47
|
+
end
|
48
|
+
|
49
|
+
def parent_id
|
50
|
+
parent_ids.first
|
51
|
+
end
|
52
|
+
|
53
|
+
# Shows the diff between the commit's parent and the commit.
|
54
|
+
#
|
55
|
+
# Cuts out the header and stats from #to_patch and returns only the diff.
|
56
|
+
def to_diff
|
57
|
+
# see Grit::Commit#show
|
58
|
+
patch = to_patch
|
59
|
+
|
60
|
+
# discard lines before the diff
|
61
|
+
lines = patch.split("\n")
|
62
|
+
while !lines.first.start_with?("diff --git") do
|
63
|
+
lines.shift
|
64
|
+
end
|
65
|
+
lines.pop if lines.last =~ /^[\d.]+$/ # Git version
|
66
|
+
lines.pop if lines.last == "-- " # end of diff
|
67
|
+
lines.join("\n")
|
68
|
+
end
|
69
|
+
|
70
|
+
def has_zero_stats?
|
71
|
+
stats.total.zero?
|
72
|
+
rescue
|
73
|
+
true
|
74
|
+
end
|
75
|
+
|
76
|
+
def no_commit_message
|
77
|
+
"--no commit message"
|
78
|
+
end
|
79
|
+
|
80
|
+
def to_hash
|
81
|
+
hash = {}
|
82
|
+
|
83
|
+
keys = serialize_keys
|
84
|
+
|
85
|
+
keys.each do |key|
|
86
|
+
hash[key] = send(key)
|
87
|
+
end
|
88
|
+
|
89
|
+
hash
|
90
|
+
end
|
91
|
+
|
92
|
+
def date
|
93
|
+
committed_date
|
94
|
+
end
|
95
|
+
|
96
|
+
def diffs
|
97
|
+
raw_commit.diffs.map { |diff| Gitlab::Git::Diff.new(diff) }
|
98
|
+
end
|
99
|
+
|
100
|
+
def parents
|
101
|
+
raw_commit.parents
|
102
|
+
end
|
103
|
+
|
104
|
+
def tree
|
105
|
+
raw_commit.tree
|
106
|
+
end
|
107
|
+
|
108
|
+
def stats
|
109
|
+
raw_commit.tree
|
110
|
+
end
|
111
|
+
|
112
|
+
def to_patch
|
113
|
+
raw_commit.to_patch
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def init_from_grit(grit)
|
119
|
+
@raw_commit = grit
|
120
|
+
@id = grit.id
|
121
|
+
@message = grit.message
|
122
|
+
@authored_date = grit.authored_date
|
123
|
+
@committed_date = grit.committed_date
|
124
|
+
@author_name = grit.author.name
|
125
|
+
@author_email = grit.author.email
|
126
|
+
@committer_name = grit.committer.name
|
127
|
+
@committer_email = grit.committer.email
|
128
|
+
@parent_ids = grit.parents.map(&:id)
|
129
|
+
end
|
130
|
+
|
131
|
+
def init_from_hash(hash)
|
132
|
+
raw_commit = hash.symbolize_keys
|
133
|
+
|
134
|
+
serialize_keys.each do |key|
|
135
|
+
send(:"#{key}=", raw_commit[key.to_sym])
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Gitlab
|
2
|
+
module Git
|
3
|
+
class Compare
|
4
|
+
attr_accessor :commits, :commit, :diffs, :same
|
5
|
+
|
6
|
+
def initialize(repository, from, to)
|
7
|
+
@commits, @diffs = [], []
|
8
|
+
@commit = nil
|
9
|
+
@same = false
|
10
|
+
|
11
|
+
return unless from && to
|
12
|
+
|
13
|
+
first = repository.commit(to.try(:strip))
|
14
|
+
last = repository.commit(from.try(:strip))
|
15
|
+
|
16
|
+
return unless first && last
|
17
|
+
|
18
|
+
if first.id == last.id
|
19
|
+
@same = true
|
20
|
+
return
|
21
|
+
end
|
22
|
+
|
23
|
+
@commit = first
|
24
|
+
@commits = repository.commits_between(last.id, first.id)
|
25
|
+
|
26
|
+
@diffs = if @commits.size > 100
|
27
|
+
[]
|
28
|
+
else
|
29
|
+
repository.repo.diff(last.id, first.id) rescue []
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Gitlab::Git::Diff is a wrapper around native Grit::Diff object
|
2
|
+
# We dont want to use grit objects inside app/
|
3
|
+
# It helps us easily migrate to rugged in future
|
4
|
+
module Gitlab
|
5
|
+
module Git
|
6
|
+
class Diff
|
7
|
+
BROKEN_DIFF = "--broken-diff"
|
8
|
+
|
9
|
+
attr_accessor :raw_diff
|
10
|
+
|
11
|
+
# Diff properties
|
12
|
+
attr_accessor :old_path, :new_path, :a_mode, :b_mode, :diff
|
13
|
+
|
14
|
+
# Stats properties
|
15
|
+
attr_accessor :new_file, :renamed_file, :deleted_file
|
16
|
+
|
17
|
+
def initialize(raw_diff)
|
18
|
+
raise "Nil as raw diff passed" unless raw_diff
|
19
|
+
|
20
|
+
if raw_diff.is_a?(Hash)
|
21
|
+
init_from_hash(raw_diff)
|
22
|
+
else
|
23
|
+
init_from_grit(raw_diff)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def serialize_keys
|
28
|
+
@serialize_keys ||= %w(diff new_path old_path a_mode b_mode new_file renamed_file deleted_file).map(&:to_sym)
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_hash
|
32
|
+
hash = {}
|
33
|
+
|
34
|
+
keys = serialize_keys
|
35
|
+
|
36
|
+
keys.each do |key|
|
37
|
+
hash[key] = send(key)
|
38
|
+
end
|
39
|
+
|
40
|
+
hash
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def init_from_grit(grit)
|
46
|
+
@raw_diff = grit
|
47
|
+
|
48
|
+
serialize_keys.each do |key|
|
49
|
+
send(:"#{key}=", grit.send(key))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def init_from_hash(hash)
|
54
|
+
raw_diff = hash.symbolize_keys
|
55
|
+
|
56
|
+
serialize_keys.each do |key|
|
57
|
+
send(:"#{key}=", raw_diff[key.to_sym])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Gitlab
|
2
|
+
module Git
|
3
|
+
module Popen
|
4
|
+
def popen(cmd, path)
|
5
|
+
vars = { "PWD" => path }
|
6
|
+
options = { :chdir => path }
|
7
|
+
|
8
|
+
@cmd_output = ""
|
9
|
+
@cmd_status = 0
|
10
|
+
Open3.popen3(vars, cmd, options) do |stdin, stdout, stderr, wait_thr|
|
11
|
+
@cmd_status = wait_thr.value.exitstatus
|
12
|
+
@cmd_output << stdout.read
|
13
|
+
@cmd_output << stderr.read
|
14
|
+
end
|
15
|
+
|
16
|
+
return @cmd_output, @cmd_status
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
# Gitlab::Git::Gitlab::Git::Commit is a wrapper around native Grit::Repository object
|
2
|
+
# We dont want to use grit objects inside app/
|
3
|
+
# It helps us easily migrate to rugged in future
|
4
|
+
module Gitlab
|
5
|
+
module Git
|
6
|
+
class Repository
|
7
|
+
include Gitlab::Git::Popen
|
8
|
+
|
9
|
+
class NoRepository < StandardError; end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_accessor :repos_path
|
13
|
+
end
|
14
|
+
|
15
|
+
# Repository directory name with namespace direcotry
|
16
|
+
# Examples:
|
17
|
+
# gitlab/gitolite
|
18
|
+
# diaspora
|
19
|
+
#
|
20
|
+
attr_accessor :path_with_namespace
|
21
|
+
|
22
|
+
# Grit repo object
|
23
|
+
attr_accessor :repo
|
24
|
+
|
25
|
+
# Default branch in the repository
|
26
|
+
attr_accessor :root_ref
|
27
|
+
|
28
|
+
def initialize(path_with_namespace, root_ref = 'master')
|
29
|
+
@root_ref = root_ref || "master"
|
30
|
+
@path_with_namespace = path_with_namespace
|
31
|
+
|
32
|
+
# Init grit repo object
|
33
|
+
repo
|
34
|
+
end
|
35
|
+
|
36
|
+
def raw
|
37
|
+
repo
|
38
|
+
end
|
39
|
+
|
40
|
+
def path_to_repo
|
41
|
+
@path_to_repo ||= File.join(repos_path, "#{path_with_namespace}.git")
|
42
|
+
end
|
43
|
+
|
44
|
+
def repos_path
|
45
|
+
self.class.repos_path
|
46
|
+
end
|
47
|
+
|
48
|
+
def repo
|
49
|
+
@repo ||= Grit::Repo.new(path_to_repo)
|
50
|
+
rescue Grit::NoSuchPathError
|
51
|
+
raise NoRepository.new('no repository for such path')
|
52
|
+
end
|
53
|
+
|
54
|
+
def commit(commit_id = nil)
|
55
|
+
commit = if commit_id
|
56
|
+
# Find repo.refs first,
|
57
|
+
# because if commit_id is "tag name",
|
58
|
+
# repo.commit(commit_id) returns wrong commit sha
|
59
|
+
# that is git tag object sha.
|
60
|
+
ref = repo.refs.find {|r| r.name == commit_id}
|
61
|
+
if ref
|
62
|
+
ref.commit
|
63
|
+
else
|
64
|
+
repo.commit(commit_id)
|
65
|
+
end
|
66
|
+
else
|
67
|
+
repo.commits(root_ref).first
|
68
|
+
end
|
69
|
+
|
70
|
+
decorate_commit(commit) if commit
|
71
|
+
end
|
72
|
+
|
73
|
+
def commits_with_refs(n = 20)
|
74
|
+
commits = repo.branches.map { |ref| decorate_commit(ref.commit, ref) }
|
75
|
+
|
76
|
+
commits.sort! do |x, y|
|
77
|
+
y.committed_date <=> x.committed_date
|
78
|
+
end
|
79
|
+
|
80
|
+
commits[0..n]
|
81
|
+
end
|
82
|
+
|
83
|
+
def commits(ref, path = nil, limit = nil, offset = nil)
|
84
|
+
if path && path != ''
|
85
|
+
repo.log(ref, path, max_count: limit, skip: offset, follow: true)
|
86
|
+
elsif limit && offset
|
87
|
+
repo.commits(ref, limit.to_i, offset.to_i)
|
88
|
+
else
|
89
|
+
repo.commits(ref)
|
90
|
+
end.map{ |c| decorate_commit(c) }
|
91
|
+
end
|
92
|
+
|
93
|
+
def commits_between(from, to)
|
94
|
+
repo.commits_between(from, to).map { |c| decorate_commit(c) }
|
95
|
+
end
|
96
|
+
|
97
|
+
def last_commit_for(ref, path = nil)
|
98
|
+
commits(ref, path, 1).first
|
99
|
+
end
|
100
|
+
|
101
|
+
# Returns an Array of branch names
|
102
|
+
# sorted by name ASC
|
103
|
+
def branch_names
|
104
|
+
branches.map(&:name)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Returns an Array of Branches
|
108
|
+
def branches
|
109
|
+
repo.branches.sort_by(&:name)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Returns an Array of tag names
|
113
|
+
def tag_names
|
114
|
+
repo.tags.collect(&:name).sort.reverse
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns an Array of Tags
|
118
|
+
def tags
|
119
|
+
repo.tags.sort_by(&:name).reverse
|
120
|
+
end
|
121
|
+
|
122
|
+
# Returns an Array of branch and tag names
|
123
|
+
def ref_names
|
124
|
+
[branch_names + tag_names].flatten
|
125
|
+
end
|
126
|
+
|
127
|
+
def heads
|
128
|
+
@heads ||= repo.heads
|
129
|
+
end
|
130
|
+
|
131
|
+
def tree(fcommit, path = nil)
|
132
|
+
fcommit = commit if fcommit == :head
|
133
|
+
tree = fcommit.tree
|
134
|
+
path ? (tree / path) : tree
|
135
|
+
end
|
136
|
+
|
137
|
+
def has_commits?
|
138
|
+
!!commit
|
139
|
+
rescue Grit::NoSuchPathError
|
140
|
+
false
|
141
|
+
end
|
142
|
+
|
143
|
+
def empty?
|
144
|
+
!has_commits?
|
145
|
+
end
|
146
|
+
|
147
|
+
# Discovers the default branch based on the repository's available branches
|
148
|
+
#
|
149
|
+
# - If no branches are present, returns nil
|
150
|
+
# - If one branch is present, returns its name
|
151
|
+
# - If two or more branches are present, returns the one that has a name
|
152
|
+
# matching root_ref (default_branch or 'master' if default_branch is nil)
|
153
|
+
def discover_default_branch
|
154
|
+
if branch_names.length == 0
|
155
|
+
nil
|
156
|
+
elsif branch_names.length == 1
|
157
|
+
branch_names.first
|
158
|
+
else
|
159
|
+
branch_names.select { |v| v == root_ref }.first
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Archive Project to .tar.gz
|
164
|
+
#
|
165
|
+
# Already packed repo archives stored at
|
166
|
+
# app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz
|
167
|
+
#
|
168
|
+
def archive_repo(ref)
|
169
|
+
ref = ref || self.root_ref
|
170
|
+
commit = self.commit(ref)
|
171
|
+
return nil unless commit
|
172
|
+
|
173
|
+
# Build file path
|
174
|
+
file_name = self.path_with_namespace.gsub("/","_") + "-" + commit.id.to_s + ".tar.gz"
|
175
|
+
storage_path = Rails.root.join("tmp", "repositories")
|
176
|
+
file_path = File.join(storage_path, self.path_with_namespace, file_name)
|
177
|
+
|
178
|
+
# Put files into a directory before archiving
|
179
|
+
prefix = File.basename(self.path_with_namespace) + "/"
|
180
|
+
|
181
|
+
# Create file if not exists
|
182
|
+
unless File.exists?(file_path)
|
183
|
+
FileUtils.mkdir_p File.dirname(file_path)
|
184
|
+
file = self.repo.archive_to_file(ref, prefix, file_path)
|
185
|
+
end
|
186
|
+
|
187
|
+
file_path
|
188
|
+
end
|
189
|
+
|
190
|
+
# Return repo size in megabytes
|
191
|
+
# Cached in redis
|
192
|
+
def size
|
193
|
+
Rails.cache.fetch(cache_key(:size)) do
|
194
|
+
size = popen('du -s', path_to_repo).first.strip.to_i
|
195
|
+
(size.to_f / 1024).round(2)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def expire_cache
|
200
|
+
Rails.cache.delete(cache_key(:size))
|
201
|
+
end
|
202
|
+
|
203
|
+
def cache_key(type)
|
204
|
+
"#{type}:#{path_with_namespace}"
|
205
|
+
end
|
206
|
+
|
207
|
+
def diffs_between(source_branch, target_branch)
|
208
|
+
# Only show what is new in the source branch compared to the target branch, not the other way around.
|
209
|
+
# The linex below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
|
210
|
+
# From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
|
211
|
+
common_commit = repo.git.native(:merge_base, {}, [target_branch, source_branch]).strip
|
212
|
+
repo.diff(common_commit, source_branch).map { |diff| Gitlab::Git::Diff.new(diff) }
|
213
|
+
|
214
|
+
rescue Grit::Git::GitTimeout
|
215
|
+
[Gitlab::Git::Diff::BROKEN_DIFF]
|
216
|
+
end
|
217
|
+
|
218
|
+
protected
|
219
|
+
|
220
|
+
def decorate_commit(commit, ref = nil)
|
221
|
+
Gitlab::Git::Commit.new(commit, ref)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Gitlab
|
2
|
+
module Git
|
3
|
+
class Stats
|
4
|
+
attr_accessor :repo, :ref
|
5
|
+
|
6
|
+
def initialize repo, ref
|
7
|
+
@repo, @ref = repo, ref
|
8
|
+
end
|
9
|
+
|
10
|
+
def authors
|
11
|
+
@authors ||= collect_authors
|
12
|
+
end
|
13
|
+
|
14
|
+
def commits_count
|
15
|
+
@commits_count ||= repo.commit_count(ref)
|
16
|
+
end
|
17
|
+
|
18
|
+
def files_count
|
19
|
+
args = [ref, '-r', '--name-only' ]
|
20
|
+
repo.git.run(nil, 'ls-tree', nil, {}, args).split("\n").count
|
21
|
+
end
|
22
|
+
|
23
|
+
def authors_count
|
24
|
+
authors.size
|
25
|
+
end
|
26
|
+
|
27
|
+
def graph
|
28
|
+
@graph ||= build_graph
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def collect_authors
|
34
|
+
shortlog = repo.git.shortlog({e: true, s: true }, ref)
|
35
|
+
|
36
|
+
authors = []
|
37
|
+
|
38
|
+
lines = shortlog.split("\n")
|
39
|
+
|
40
|
+
lines.each do |line|
|
41
|
+
data = line.split("\t")
|
42
|
+
commits = data.first
|
43
|
+
author = Grit::Actor.from_string(data.last)
|
44
|
+
|
45
|
+
authors << OpenStruct.new(
|
46
|
+
name: author.name,
|
47
|
+
email: author.email,
|
48
|
+
commits: commits.to_i
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
authors.sort_by(&:commits).reverse
|
53
|
+
end
|
54
|
+
|
55
|
+
def build_graph n = 4
|
56
|
+
from, to = (Date.today.prev_day(n*7)), Date.today
|
57
|
+
args = ['--all', "--since=#{from.to_s}", '--format=%ad' ]
|
58
|
+
rev_list = repo.git.run(nil, 'rev-list', nil, {}, args).split("\n")
|
59
|
+
|
60
|
+
commits_dates = rev_list.values_at(* rev_list.each_index.select {|i| i.odd?})
|
61
|
+
commits_dates = commits_dates.map { |date_str| Time.parse(date_str).to_date.to_s(:date) }
|
62
|
+
|
63
|
+
commits_per_day = from.upto(to).map do |day|
|
64
|
+
commits_dates.count(day.to_date.to_s)
|
65
|
+
end
|
66
|
+
|
67
|
+
OpenStruct.new(
|
68
|
+
labels: from.upto(to).map { |day| day.strftime('%b %d') },
|
69
|
+
commits: commits_per_day,
|
70
|
+
weeks: n
|
71
|
+
)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Gitlab
|
2
|
+
module Git
|
3
|
+
class Tree
|
4
|
+
attr_accessor :repository, :sha, :path, :ref, :raw_tree, :id
|
5
|
+
|
6
|
+
def initialize(repository, sha, ref = nil, path = nil)
|
7
|
+
@repository, @sha, @ref, @path = repository, sha, ref, path
|
8
|
+
|
9
|
+
@path = nil if !@path || @path == ''
|
10
|
+
|
11
|
+
# Load tree from repository
|
12
|
+
@commit = @repository.commit(@sha)
|
13
|
+
@raw_tree = @repository.tree(@commit, @path)
|
14
|
+
end
|
15
|
+
|
16
|
+
def exists?
|
17
|
+
raw_tree
|
18
|
+
end
|
19
|
+
|
20
|
+
def empty?
|
21
|
+
trees.empty? && blobs.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
def trees
|
25
|
+
entries.select { |t| t.is_a?(Grit::Tree) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def blobs
|
29
|
+
entries.select { |t| t.is_a?(Grit::Blob) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def is_blob?
|
33
|
+
raw_tree.is_a?(Grit::Blob)
|
34
|
+
end
|
35
|
+
|
36
|
+
def up_dir?
|
37
|
+
path && path != ''
|
38
|
+
end
|
39
|
+
|
40
|
+
def readme
|
41
|
+
@readme ||= blobs.find { |c| c.name =~ /^readme/i }
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def entries
|
47
|
+
raw_tree.contents
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab_git
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dmitriy Zaporozhets
|
@@ -73,6 +73,15 @@ extensions: []
|
|
73
73
|
extra_rdoc_files: []
|
74
74
|
files:
|
75
75
|
- lib/gitlab_git.rb
|
76
|
+
- lib/gitlab_git/blame.rb
|
77
|
+
- lib/gitlab_git/blob.rb
|
78
|
+
- lib/gitlab_git/commit.rb
|
79
|
+
- lib/gitlab_git/compare.rb
|
80
|
+
- lib/gitlab_git/diff.rb
|
81
|
+
- lib/gitlab_git/popen.rb
|
82
|
+
- lib/gitlab_git/repository.rb
|
83
|
+
- lib/gitlab_git/stats.rb
|
84
|
+
- lib/gitlab_git/tree.rb
|
76
85
|
homepage: http://rubygems.org/gems/gitlab_git
|
77
86
|
licenses: []
|
78
87
|
metadata: {}
|