gitlab_git 1.4.1 → 2.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- 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
|