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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d590d7ff3fab5e14714b50c3834566f326ef20af
4
- data.tar.gz: 40e19943e01067a42f9ef8ba906a1e7b618d146c
3
+ metadata.gz: 721ce63ea203619c49c42fd796634d7076ebad3b
4
+ data.tar.gz: 3d7ac5846bc15878beddfedb4bc8378048359d43
5
5
  SHA512:
6
- metadata.gz: 0e589b34aea8ebb6397ba01b6367313b4a5725be1990dd86f5cee2077e9476969a34d239651452797035431397a646d56a1b90ba02a527273570769ebd0c34ef
7
- data.tar.gz: 8a7707289c1bdc7feadaaa8a9cba4aefefd8bcec7b8dc1212725495fd697893fe405583eeb644317ce7622101992c485ff01bf20a90978a8015942ea2da1dd1b
6
+ metadata.gz: 216f0f37fa7f9b38ce2bf9710ed9773210af4128e6f874124f0c5e26865fcf9739ef8d38cddea671c05c195fe7021dd4287a1d8f2511f8618400539e1833c799
7
+ data.tar.gz: 4df9626fbf0a5c1c18d603d64bc93fa7a998dccddaac7ae424461bbf36fc11b0f9e73f7817f6beb456cb43fcb89e2d124da2d1fe439e00a08f5676adf146235f
@@ -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.repo, sha, path)
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
@@ -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
 
@@ -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
 
@@ -10,7 +10,8 @@ module Gitlab
10
10
  end
11
11
 
12
12
  def log
13
- args = ['--format=%aN%x0a%ad', '--date=short', '--shortstat', '--no-merges']
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: {author, date, additions, deletions}
6
- def self.parse_log log_from_git
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
- while i <= log.size do
14
- pos = i % 4
15
- case pos
16
- when 0
17
- unless i == 0
18
- collection.push(entry)
19
- entry = {}
20
- end
21
- entry[:author] = log[i].to_s
22
- when 1
23
- entry[:date] = log[i].to_s
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::Gitlab::Git::Commit is a wrapper around native Grit::Repository object
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
- repo
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 repo
49
- @repo ||= Grit::Repo.new(path_to_repo)
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
- repo.branches.sort_by(&:name)
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
- repo.tags.sort_by(&:name).reverse
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 ||= repo.heads.sort_by(&:name)
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
- !!commit
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 = self.commit(ref)
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.repo.archive_to_file(ref, prefix, file_path)
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 = repo.grep(query, 3, ref)
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
- protected
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 decorate_commit(commit, ref = nil)
221
- Gitlab::Git::Commit.new(commit, ref)
199
+ def diff(from, to)
200
+ raw.diff(from, to)
222
201
  end
223
202
  end
224
203
  end
@@ -9,7 +9,7 @@ module Gitlab
9
9
  @path = nil if !@path || @path == ''
10
10
 
11
11
  # Load tree from repository
12
- @commit = @repository.commit(@sha)
12
+ @commit = Gitlab::Git::Commit.find(@repository, @sha)
13
13
  @raw_tree = @repository.tree(@commit, @path)
14
14
  end
15
15
 
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.4.1
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: '0'
91
+ version: 1.3.1
92
92
  requirements: []
93
93
  rubyforge_project:
94
94
  rubygems_version: 2.0.3