gitlab_git 1.4.1 → 2.0.0.beta
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 +1 -2
- data/lib/gitlab_git/commit.rb +83 -0
- data/lib/gitlab_git/diff.rb +15 -0
- data/lib/gitlab_git/git_stats.rb +2 -1
- data/lib/gitlab_git/log_parser.rb +14 -22
- data/lib/gitlab_git/repository.rb +58 -79
- data/lib/gitlab_git/tree.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 721ce63ea203619c49c42fd796634d7076ebad3b
|
4
|
+
data.tar.gz: 3d7ac5846bc15878beddfedb4bc8378048359d43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 216f0f37fa7f9b38ce2bf9710ed9773210af4128e6f874124f0c5e26865fcf9739ef8d38cddea671c05c195fe7021dd4287a1d8f2511f8618400539e1833c799
|
7
|
+
data.tar.gz: 4df9626fbf0a5c1c18d603d64bc93fa7a998dccddaac7ae424461bbf36fc11b0f9e73f7817f6beb456cb43fcb89e2d124da2d1fe439e00a08f5676adf146235f
|
data/lib/gitlab_git/blame.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module Gitlab
|
2
2
|
module Git
|
3
3
|
class Blame
|
4
|
-
|
5
4
|
attr_accessor :repository, :sha, :path
|
6
5
|
|
7
6
|
def initialize(repository, sha, path)
|
@@ -9,7 +8,7 @@ module Gitlab
|
|
9
8
|
end
|
10
9
|
|
11
10
|
def each
|
12
|
-
raw_blame = Grit::Blob.blame(repository.
|
11
|
+
raw_blame = Grit::Blob.blame(repository.raw, sha, path)
|
13
12
|
|
14
13
|
raw_blame.each do |commit, lines|
|
15
14
|
next unless commit
|
data/lib/gitlab_git/commit.rb
CHANGED
@@ -13,6 +13,89 @@ module Gitlab
|
|
13
13
|
]
|
14
14
|
attr_accessor *SERIALIZE_KEYS
|
15
15
|
|
16
|
+
class << self
|
17
|
+
# Get commits collection
|
18
|
+
#
|
19
|
+
# Ex.
|
20
|
+
# Commit.where(
|
21
|
+
# repo: repo,
|
22
|
+
# ref: 'master',
|
23
|
+
# path: 'app/models',
|
24
|
+
# limit: 10,
|
25
|
+
# offset: 5,
|
26
|
+
# )
|
27
|
+
#
|
28
|
+
def where(options)
|
29
|
+
repo = options.delete(:repo)
|
30
|
+
raise 'Gitlab::Git::Repository is required' unless repo.respond_to?(:log)
|
31
|
+
|
32
|
+
repo.log(options).map { |c| decorate(c) }
|
33
|
+
end
|
34
|
+
|
35
|
+
# Get single commit
|
36
|
+
#
|
37
|
+
# Ex.
|
38
|
+
# Commit.find(repo, '29eda46b')
|
39
|
+
#
|
40
|
+
# Commit.find(repo, 'master')
|
41
|
+
#
|
42
|
+
def find(repo, commit_id = nil)
|
43
|
+
# Find repo.tags first,
|
44
|
+
# because if commit_id is "tag name",
|
45
|
+
# repo.commit(commit_id) returns wrong commit sha
|
46
|
+
# that is git tag object sha.
|
47
|
+
tag = repo.tags.find {|tag| tag.name == commit_id} if commit_id
|
48
|
+
|
49
|
+
commit = if tag
|
50
|
+
tag.commit
|
51
|
+
else
|
52
|
+
repo.log(ref: commit_id).first
|
53
|
+
end
|
54
|
+
|
55
|
+
decorate(commit) if commit
|
56
|
+
end
|
57
|
+
|
58
|
+
# Get last commit for HEAD
|
59
|
+
#
|
60
|
+
# Ex.
|
61
|
+
# Commit.last(repo)
|
62
|
+
#
|
63
|
+
def last(repo)
|
64
|
+
find(repo, nil)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Get last commit for specified path and ref
|
68
|
+
#
|
69
|
+
# Ex.
|
70
|
+
# Commit.last_for_path(repo, '29eda46b', 'app/models')
|
71
|
+
#
|
72
|
+
# Commit.last_for_path(repo, 'master', 'Gemfile')
|
73
|
+
#
|
74
|
+
def last_for_path(repo, ref, path = nil)
|
75
|
+
where(
|
76
|
+
repo: repo,
|
77
|
+
ref: ref,
|
78
|
+
path: path,
|
79
|
+
limit: 1
|
80
|
+
).first
|
81
|
+
end
|
82
|
+
|
83
|
+
# Get commits between two refs
|
84
|
+
#
|
85
|
+
# Ex.
|
86
|
+
# Commit.between('29eda46b', 'master')
|
87
|
+
#
|
88
|
+
def between(repo, from, to)
|
89
|
+
repo.commits_between(from, to).map do |commit|
|
90
|
+
decorate(commit)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def decorate(commit, ref = nil)
|
95
|
+
Gitlab::Git::Commit.new(commit, ref)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
16
99
|
def initialize(raw_commit, head = nil)
|
17
100
|
raise "Nil as raw commit passed" unless raw_commit
|
18
101
|
|
data/lib/gitlab_git/diff.rb
CHANGED
@@ -14,6 +14,21 @@ module Gitlab
|
|
14
14
|
# Stats properties
|
15
15
|
attr_accessor :new_file, :renamed_file, :deleted_file
|
16
16
|
|
17
|
+
class << self
|
18
|
+
def between(repo, from, to)
|
19
|
+
# Only show what is new in the source branch compared to the target branch, not the other way around.
|
20
|
+
# The linex below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
|
21
|
+
# From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
|
22
|
+
common_commit = repo.merge_base_commit(from, to)
|
23
|
+
|
24
|
+
repo.diff(common_commit, from).map do |diff|
|
25
|
+
Gitlab::Git::Diff.new(diff)
|
26
|
+
end
|
27
|
+
rescue Grit::Git::GitTimeout
|
28
|
+
[Gitlab::Git::Diff::BROKEN_DIFF]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
17
32
|
def initialize(raw_diff)
|
18
33
|
raise "Nil as raw diff passed" unless raw_diff
|
19
34
|
|
data/lib/gitlab_git/git_stats.rb
CHANGED
@@ -10,7 +10,8 @@ module Gitlab
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def log
|
13
|
-
|
13
|
+
# Limit log to 8k commits to avoid timeout for huge projects
|
14
|
+
args = ['--format=%aN%x0a%aE%x0a%ad', '--date=short', '--shortstat', '--no-merges', '--max-count=8000']
|
14
15
|
repo.git.run(nil, 'log', nil, {}, args)
|
15
16
|
rescue Grit::Git::GitTimeout
|
16
17
|
nil
|
@@ -2,31 +2,23 @@ module Gitlab
|
|
2
2
|
module Git
|
3
3
|
class LogParser
|
4
4
|
# Parses the log file into a collection of commits
|
5
|
-
# Data model:
|
6
|
-
|
5
|
+
# Data model:
|
6
|
+
# {author_name, author_email, date, additions, deletions}
|
7
|
+
def self.parse_log(log_from_git)
|
7
8
|
log = log_from_git.split("\n")
|
8
|
-
|
9
|
-
i = 0
|
10
9
|
collection = []
|
11
|
-
entry = {}
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
when 3
|
25
|
-
changes = log[i].split(",")
|
26
|
-
entry[:additions] = changes[1].to_i unless changes[1].nil?
|
27
|
-
entry[:deletions] = changes[2].to_i unless changes[2].nil?
|
28
|
-
end
|
29
|
-
i += 1
|
11
|
+
log.each_slice(5) do |slice|
|
12
|
+
entry = {}
|
13
|
+
entry[:author_name] = slice[0]
|
14
|
+
entry[:author_email] = slice[1]
|
15
|
+
entry[:date] = slice[2]
|
16
|
+
|
17
|
+
changes = slice[4].split(",")
|
18
|
+
entry[:additions] = changes[1].to_i unless changes[1].nil?
|
19
|
+
entry[:deletions] = changes[2].to_i unless changes[2].nil?
|
20
|
+
|
21
|
+
collection.push(entry)
|
30
22
|
end
|
31
23
|
|
32
24
|
collection
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Gitlab::Git::
|
1
|
+
# Gitlab::Git::Commit is a wrapper around native Grit::Repository object
|
2
2
|
# We dont want to use grit objects inside app/
|
3
3
|
# It helps us easily migrate to rugged in future
|
4
4
|
module Gitlab
|
@@ -19,22 +19,21 @@ module Gitlab
|
|
19
19
|
#
|
20
20
|
attr_accessor :path_with_namespace
|
21
21
|
|
22
|
-
# Grit repo object
|
23
|
-
attr_accessor :repo
|
24
|
-
|
25
22
|
# Default branch in the repository
|
26
23
|
attr_accessor :root_ref
|
27
24
|
|
25
|
+
# Grit repo object
|
26
|
+
attr_reader :raw
|
27
|
+
|
28
|
+
# compatibility
|
29
|
+
alias_method :repo, :raw
|
30
|
+
|
28
31
|
def initialize(path_with_namespace, root_ref = 'master')
|
29
32
|
@root_ref = root_ref || "master"
|
30
33
|
@path_with_namespace = path_with_namespace
|
31
34
|
|
32
35
|
# Init grit repo object
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
def raw
|
37
|
-
repo
|
36
|
+
raw
|
38
37
|
end
|
39
38
|
|
40
39
|
def path_to_repo
|
@@ -45,59 +44,12 @@ module Gitlab
|
|
45
44
|
self.class.repos_path
|
46
45
|
end
|
47
46
|
|
48
|
-
def
|
49
|
-
@
|
47
|
+
def raw
|
48
|
+
@raw ||= Grit::Repo.new(path_to_repo)
|
50
49
|
rescue Grit::NoSuchPathError
|
51
50
|
raise NoRepository.new('no repository for such path')
|
52
51
|
end
|
53
52
|
|
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
53
|
# Returns an Array of branch names
|
102
54
|
# sorted by name ASC
|
103
55
|
def branch_names
|
@@ -106,7 +58,7 @@ module Gitlab
|
|
106
58
|
|
107
59
|
# Returns an Array of Branches
|
108
60
|
def branches
|
109
|
-
|
61
|
+
raw.branches.sort_by(&:name)
|
110
62
|
end
|
111
63
|
|
112
64
|
# Returns an Array of tag names
|
@@ -116,7 +68,7 @@ module Gitlab
|
|
116
68
|
|
117
69
|
# Returns an Array of Tags
|
118
70
|
def tags
|
119
|
-
|
71
|
+
raw.tags.sort_by(&:name).reverse
|
120
72
|
end
|
121
73
|
|
122
74
|
# Returns an Array of branch and tag names
|
@@ -125,7 +77,7 @@ module Gitlab
|
|
125
77
|
end
|
126
78
|
|
127
79
|
def heads
|
128
|
-
@heads ||=
|
80
|
+
@heads ||= raw.heads.sort_by(&:name)
|
129
81
|
end
|
130
82
|
|
131
83
|
def tree(fcommit, path = nil)
|
@@ -135,7 +87,7 @@ module Gitlab
|
|
135
87
|
end
|
136
88
|
|
137
89
|
def has_commits?
|
138
|
-
!!
|
90
|
+
!!Gitlab::Git::Commit.last(self)
|
139
91
|
rescue Grit::NoSuchPathError
|
140
92
|
false
|
141
93
|
end
|
@@ -167,7 +119,7 @@ module Gitlab
|
|
167
119
|
#
|
168
120
|
def archive_repo(ref, storage_path)
|
169
121
|
ref = ref || self.root_ref
|
170
|
-
commit =
|
122
|
+
commit = Gitlab::Git::Commit.find(self, ref)
|
171
123
|
return nil unless commit
|
172
124
|
|
173
125
|
# Build file path
|
@@ -180,7 +132,7 @@ module Gitlab
|
|
180
132
|
# Create file if not exists
|
181
133
|
unless File.exists?(file_path)
|
182
134
|
FileUtils.mkdir_p File.dirname(file_path)
|
183
|
-
file = self.
|
135
|
+
file = self.raw.archive_to_file(ref, prefix, file_path)
|
184
136
|
end
|
185
137
|
|
186
138
|
file_path
|
@@ -192,33 +144,60 @@ module Gitlab
|
|
192
144
|
(size.to_f / 1024).round(2)
|
193
145
|
end
|
194
146
|
|
195
|
-
def diffs_between(source_branch, target_branch)
|
196
|
-
# Only show what is new in the source branch compared to the target branch, not the other way around.
|
197
|
-
# The linex below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
|
198
|
-
# From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
|
199
|
-
common_commit = repo.git.native(:merge_base, {}, [target_branch, source_branch]).strip
|
200
|
-
repo.diff(common_commit, source_branch).map { |diff| Gitlab::Git::Diff.new(diff) }
|
201
|
-
|
202
|
-
rescue Grit::Git::GitTimeout
|
203
|
-
[Gitlab::Git::Diff::BROKEN_DIFF]
|
204
|
-
end
|
205
|
-
|
206
147
|
def search_files(query, ref = nil)
|
207
148
|
if ref.nil? || ref == ""
|
208
149
|
ref = root_ref
|
209
150
|
end
|
210
151
|
|
211
|
-
greps =
|
152
|
+
greps = raw.grep(query, 3, ref)
|
212
153
|
|
213
154
|
greps.map do |grep|
|
214
155
|
Gitlab::Git::BlobSnippet.new(ref, grep.content, grep.startline, grep.filename)
|
215
156
|
end
|
216
157
|
end
|
217
158
|
|
218
|
-
|
159
|
+
# Delegate log to Grit method
|
160
|
+
#
|
161
|
+
# Usage.
|
162
|
+
# repo.log(
|
163
|
+
# ref: 'master',
|
164
|
+
# path: 'app/models',
|
165
|
+
# limit: 10,
|
166
|
+
# offset: 5,
|
167
|
+
# )
|
168
|
+
#
|
169
|
+
def log(options)
|
170
|
+
default_options = {
|
171
|
+
limit: 10,
|
172
|
+
offset: 0,
|
173
|
+
path: nil,
|
174
|
+
ref: root_ref,
|
175
|
+
follow: false
|
176
|
+
}
|
177
|
+
|
178
|
+
options = default_options.merge(options)
|
179
|
+
|
180
|
+
raw.log(
|
181
|
+
options[:ref] || root_ref,
|
182
|
+
options[:path],
|
183
|
+
max_count: options[:limit].to_i,
|
184
|
+
skip: options[:offset].to_i,
|
185
|
+
follow: options[:follow]
|
186
|
+
)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Delegate commits_between to Grit method
|
190
|
+
#
|
191
|
+
def commits_between(from, to)
|
192
|
+
raw.commits_between(from, to)
|
193
|
+
end
|
194
|
+
|
195
|
+
def merge_base_commit(from, to)
|
196
|
+
raw.git.native(:merge_base, {}, [to, from]).strip
|
197
|
+
end
|
219
198
|
|
220
|
-
def
|
221
|
-
|
199
|
+
def diff(from, to)
|
200
|
+
raw.diff(from, to)
|
222
201
|
end
|
223
202
|
end
|
224
203
|
end
|
data/lib/gitlab_git/tree.rb
CHANGED
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:
|
4
|
+
version: 2.0.0.beta
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dmitriy Zaporozhets
|
@@ -86,9 +86,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
86
86
|
version: '0'
|
87
87
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
88
|
requirements:
|
89
|
-
- - '
|
89
|
+
- - '>'
|
90
90
|
- !ruby/object:Gem::Version
|
91
|
-
version:
|
91
|
+
version: 1.3.1
|
92
92
|
requirements: []
|
93
93
|
rubyforge_project:
|
94
94
|
rubygems_version: 2.0.3
|