smeagol 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.index +82 -0
  3. data/HISTORY.md +14 -0
  4. data/lib/smeagol.rb +2 -1
  5. data/lib/smeagol/app.rb +1 -1
  6. data/lib/smeagol/gollum/file.rb +1 -1
  7. data/lib/smeagol/wiki.rb +1 -0
  8. data/vendor/grit/lib/grit.rb +75 -0
  9. data/vendor/grit/lib/grit/actor.rb +52 -0
  10. data/vendor/grit/lib/grit/blame.rb +70 -0
  11. data/vendor/grit/lib/grit/blob.rb +126 -0
  12. data/vendor/grit/lib/grit/commit.rb +313 -0
  13. data/vendor/grit/lib/grit/commit_stats.rb +128 -0
  14. data/vendor/grit/lib/grit/config.rb +44 -0
  15. data/vendor/grit/lib/grit/diff.rb +79 -0
  16. data/vendor/grit/lib/grit/errors.rb +10 -0
  17. data/vendor/grit/lib/grit/git-ruby.rb +262 -0
  18. data/vendor/grit/lib/grit/git-ruby/commit_db.rb +52 -0
  19. data/vendor/grit/lib/grit/git-ruby/git_object.rb +353 -0
  20. data/vendor/grit/lib/grit/git-ruby/internal/file_window.rb +58 -0
  21. data/vendor/grit/lib/grit/git-ruby/internal/loose.rb +137 -0
  22. data/vendor/grit/lib/grit/git-ruby/internal/pack.rb +397 -0
  23. data/vendor/grit/lib/grit/git-ruby/internal/raw_object.rb +44 -0
  24. data/vendor/grit/lib/grit/git-ruby/repository.rb +775 -0
  25. data/vendor/grit/lib/grit/git.rb +501 -0
  26. data/vendor/grit/lib/grit/index.rb +222 -0
  27. data/vendor/grit/lib/grit/lazy.rb +35 -0
  28. data/vendor/grit/lib/grit/merge.rb +45 -0
  29. data/vendor/grit/lib/grit/ref.rb +78 -0
  30. data/vendor/grit/lib/grit/repo.rb +709 -0
  31. data/vendor/grit/lib/grit/ruby1.9.rb +7 -0
  32. data/vendor/grit/lib/grit/status.rb +153 -0
  33. data/vendor/grit/lib/grit/submodule.rb +88 -0
  34. data/vendor/grit/lib/grit/tag.rb +102 -0
  35. data/vendor/grit/lib/grit/tree.rb +125 -0
  36. metadata +125 -56
  37. data/.ruby +0 -80
@@ -0,0 +1,313 @@
1
+ module Grit
2
+
3
+ class Commit
4
+ extend Lazy
5
+
6
+ attr_reader :id
7
+ attr_reader :repo
8
+ lazy_reader :parents
9
+ lazy_reader :tree
10
+ lazy_reader :author
11
+ lazy_reader :authored_date
12
+ lazy_reader :committer
13
+ lazy_reader :committed_date
14
+ lazy_reader :message
15
+ lazy_reader :short_message
16
+
17
+ # Parses output from the `git-cat-file --batch'.
18
+ #
19
+ # repo - Grit::Repo instance.
20
+ # sha - String SHA of the Commit.
21
+ # size - Fixnum size of the object.
22
+ # object - Parsed String output from `git cat-file --batch`.
23
+ #
24
+ # Returns an Array of Grit::Commit objects.
25
+ def self.parse_batch(repo, sha, size, object)
26
+ info, message = object.split("\n\n", 2)
27
+
28
+ lines = info.split("\n")
29
+ tree = lines.shift.split(' ', 2).last
30
+ parents = []
31
+ parents << lines.shift[7..-1] while lines.first[0, 6] == 'parent'
32
+ author, authored_date = Grit::Commit.actor(lines.shift)
33
+ committer, committed_date = Grit::Commit.actor(lines.shift)
34
+
35
+ Grit::Commit.new(
36
+ repo, sha, parents, tree,
37
+ author, authored_date,
38
+ committer, committed_date,
39
+ message.to_s.split("\n"))
40
+ end
41
+
42
+ # Instantiate a new Commit
43
+ # +id+ is the id of the commit
44
+ # +parents+ is an array of commit ids (will be converted into Commit instances)
45
+ # +tree+ is the correspdonding tree id (will be converted into a Tree object)
46
+ # +author+ is the author string
47
+ # +authored_date+ is the authored Time
48
+ # +committer+ is the committer string
49
+ # +committed_date+ is the committed Time
50
+ # +message+ is an array of commit message lines
51
+ #
52
+ # Returns Grit::Commit (baked)
53
+ def initialize(repo, id, parents, tree, author, authored_date, committer, committed_date, message)
54
+ @repo = repo
55
+ @id = id
56
+ @parents = parents.map { |p| Commit.create(repo, :id => p) }
57
+ @tree = Tree.create(repo, :id => tree)
58
+ @author = author
59
+ @authored_date = authored_date
60
+ @committer = committer
61
+ @committed_date = committed_date
62
+ @message = message.join("\n")
63
+ @short_message = message.find { |x| !x.strip.empty? } || ''
64
+ end
65
+
66
+ def id_abbrev
67
+ @id_abbrev ||= @repo.git.rev_parse({}, self.id).chomp[0, 7]
68
+ end
69
+
70
+ # Create an unbaked Commit containing just the specified attributes
71
+ # +repo+ is the Repo
72
+ # +atts+ is a Hash of instance variable data
73
+ #
74
+ # Returns Grit::Commit (unbaked)
75
+ def self.create(repo, atts)
76
+ self.allocate.create_initialize(repo, atts)
77
+ end
78
+
79
+ # Initializer for Commit.create
80
+ # +repo+ is the Repo
81
+ # +atts+ is a Hash of instance variable data
82
+ #
83
+ # Returns Grit::Commit (unbaked)
84
+ def create_initialize(repo, atts)
85
+ @repo = repo
86
+ atts.each do |k, v|
87
+ instance_variable_set("@#{k}", v)
88
+ end
89
+ self
90
+ end
91
+
92
+ def lazy_source
93
+ self.class.find_all(@repo, @id, {:max_count => 1}).first
94
+ end
95
+
96
+ # Count the number of commits reachable from this ref
97
+ # +repo+ is the Repo
98
+ # +ref+ is the ref from which to begin (SHA1 or name)
99
+ #
100
+ # Returns Integer
101
+ def self.count(repo, ref)
102
+ repo.git.rev_list({}, ref).size / 41
103
+ end
104
+
105
+ # Find all commits matching the given criteria.
106
+ # +repo+ is the Repo
107
+ # +ref+ is the ref from which to begin (SHA1 or name) or nil for --all
108
+ # +options+ is a Hash of optional arguments to git
109
+ # :max_count is the maximum number of commits to fetch
110
+ # :skip is the number of commits to skip
111
+ #
112
+ # Returns Grit::Commit[] (baked)
113
+ def self.find_all(repo, ref, options = {})
114
+ allowed_options = [:max_count, :skip, :since]
115
+
116
+ default_options = {:pretty => "raw"}
117
+ actual_options = default_options.merge(options)
118
+
119
+ if ref
120
+ output = repo.git.rev_list(actual_options, ref)
121
+ else
122
+ output = repo.git.rev_list(actual_options.merge(:all => true))
123
+ end
124
+
125
+ self.list_from_string(repo, output)
126
+ rescue Grit::GitRuby::Repository::NoSuchShaFound
127
+ []
128
+ end
129
+
130
+ # Parse out commit information into an array of baked Commit objects
131
+ # +repo+ is the Repo
132
+ # +text+ is the text output from the git command (raw format)
133
+ #
134
+ # Returns Grit::Commit[] (baked)
135
+ #
136
+ # really should re-write this to be more accepting of non-standard commit messages
137
+ # - it broke when 'encoding' was introduced - not sure what else might show up
138
+ #
139
+ def self.list_from_string(repo, text)
140
+ lines = text.split("\n")
141
+
142
+ commits = []
143
+
144
+ while !lines.empty?
145
+ id = lines.shift.split.last
146
+ tree = lines.shift.split.last
147
+
148
+ parents = []
149
+ parents << lines.shift.split.last while lines.first =~ /^parent/
150
+
151
+ author_line = lines.shift
152
+ author_line << lines.shift if lines[0] !~ /^committer /
153
+ author, authored_date = self.actor(author_line)
154
+
155
+ committer_line = lines.shift
156
+ committer_line << lines.shift if lines[0] && lines[0] != '' && lines[0] !~ /^encoding/
157
+ committer, committed_date = self.actor(committer_line)
158
+
159
+ # not doing anything with this yet, but it's sometimes there
160
+ encoding = lines.shift.split.last if lines.first =~ /^encoding/
161
+
162
+ lines.shift
163
+
164
+ message_lines = []
165
+ message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/
166
+
167
+ lines.shift while lines.first && lines.first.empty?
168
+
169
+ commits << Commit.new(repo, id, parents, tree, author, authored_date, committer, committed_date, message_lines)
170
+ end
171
+
172
+ commits
173
+ end
174
+
175
+ # Show diffs between two trees.
176
+ #
177
+ # repo - The current Grit::Repo instance.
178
+ # a - A String named commit.
179
+ # b - An optional String named commit. Passing an array assumes you
180
+ # wish to omit the second named commit and limit the diff to the
181
+ # given paths.
182
+ # paths - An optional Array of paths to limit the diff.
183
+ # options - An optional Hash of options. Merged into {:full_index => true}.
184
+ #
185
+ # Returns Grit::Diff[] (baked)
186
+ def self.diff(repo, a, b = nil, paths = [], options = {})
187
+ if b.is_a?(Array)
188
+ paths = b
189
+ b = nil
190
+ end
191
+ paths.unshift("--") unless paths.empty?
192
+ paths.unshift(b) unless b.nil?
193
+ paths.unshift(a)
194
+ options = {:full_index => true}.update(options)
195
+ text = repo.git.diff(options, *paths)
196
+ Diff.list_from_string(repo, text)
197
+ end
198
+
199
+ def show
200
+ if parents.size > 1
201
+ diff = @repo.git.native(:diff, {:full_index => true}, "#{parents[0].id}...#{parents[1].id}")
202
+ else
203
+ diff = @repo.git.show({:full_index => true, :pretty => 'raw'}, @id)
204
+ end
205
+
206
+ if diff =~ /diff --git a/
207
+ diff = diff.sub(/.+?(diff --git a)/m, '\1')
208
+ else
209
+ diff = ''
210
+ end
211
+ Diff.list_from_string(@repo, diff)
212
+ end
213
+
214
+ # Shows diffs between the commit's parent and the commit.
215
+ #
216
+ # options - An optional Hash of options, passed to Grit::Commit.diff.
217
+ #
218
+ # Returns Grit::Diff[] (baked)
219
+ def diffs(options = {})
220
+ if parents.empty?
221
+ show
222
+ else
223
+ self.class.diff(@repo, parents.first.id, @id, [], options)
224
+ end
225
+ end
226
+
227
+ def stats
228
+ stats = @repo.commit_stats(self.sha, 1)[0][-1]
229
+ end
230
+
231
+ # Convert this Commit to a String which is just the SHA1 id
232
+ def to_s
233
+ @id
234
+ end
235
+
236
+ def sha
237
+ @id
238
+ end
239
+
240
+ def date
241
+ @committed_date
242
+ end
243
+
244
+ def to_patch
245
+ @repo.git.format_patch({'1' => true, :stdout => true}, to_s)
246
+ end
247
+
248
+ def notes
249
+ ret = {}
250
+ notes = Note.find_all(@repo)
251
+ notes.each do |note|
252
+ if n = note.commit.tree/(self.id)
253
+ ret[note.name] = n.data
254
+ end
255
+ end
256
+ ret
257
+ end
258
+
259
+ # Calculates the commit's Patch ID. The Patch ID is essentially the SHA1
260
+ # of the diff that the commit is introducing.
261
+ #
262
+ # Returns the 40 character hex String if a patch-id could be calculated
263
+ # or nil otherwise.
264
+ def patch_id
265
+ show = @repo.git.show({}, @id)
266
+ patch_line = @repo.git.native(:patch_id, :input => show)
267
+ if patch_line =~ /^([0-9a-f]{40}) [0-9a-f]{40}\n$/
268
+ $1
269
+ else
270
+ nil
271
+ end
272
+ end
273
+
274
+ # Pretty object inspection
275
+ def inspect
276
+ %Q{#<Grit::Commit "#{@id}">}
277
+ end
278
+
279
+ # private
280
+
281
+ # Parse out the actor (author or committer) info
282
+ #
283
+ # Returns [String (actor name and email), Time (acted at time)]
284
+ def self.actor(line)
285
+ m, actor, epoch = *line.match(/^.+? (.*) (\d+) .*$/)
286
+ [Actor.from_string(actor), Time.at(epoch.to_i)]
287
+ end
288
+
289
+ def author_string
290
+ "%s <%s> %s %+05d" % [author.name, author.email, authored_date.to_i, 800]
291
+ end
292
+
293
+ def to_hash
294
+ {
295
+ 'id' => id,
296
+ 'parents' => parents.map { |p| { 'id' => p.id } },
297
+ 'tree' => tree.id,
298
+ 'message' => message,
299
+ 'author' => {
300
+ 'name' => author.name,
301
+ 'email' => author.email
302
+ },
303
+ 'committer' => {
304
+ 'name' => committer.name,
305
+ 'email' => committer.email
306
+ },
307
+ 'authored_date' => authored_date.xmlschema,
308
+ 'committed_date' => committed_date.xmlschema,
309
+ }
310
+ end
311
+ end # Commit
312
+
313
+ end # Grit
@@ -0,0 +1,128 @@
1
+ module Grit
2
+
3
+ class CommitStats
4
+
5
+ attr_reader :id, :files, :additions, :deletions, :total
6
+
7
+ # Instantiate a new CommitStats
8
+ # +id+ is the id of the commit
9
+ # +files+ is an array of :
10
+ # [ [filename, adds, deletes, total],
11
+ # [filename, adds, deletes, total],
12
+ # [filename, adds, deletes, total] ]
13
+ #
14
+ # Returns Grit::CommitStats (baked)
15
+ def initialize(repo, id, files)
16
+ @repo = repo
17
+ @id = id
18
+ @files = files
19
+ @additions = files.inject(0) { |total, a| total += a[1] }
20
+ @deletions = files.inject(0) { |total, a| total += a[2] }
21
+ @total = files.inject(0) { |total, a| total += a[3] }
22
+ end
23
+
24
+ # Find all commit stats matching the given criteria.
25
+ # +repo+ is the Repo
26
+ # +ref+ is the ref from which to begin (SHA1 or name) or nil for --all
27
+ # +options+ is a Hash of optional arguments to git
28
+ # :max_count is the maximum number of commits to fetch
29
+ # :skip is the number of commits to skip
30
+ #
31
+ # Returns assoc array [sha, Grit::Commit[] (baked)]
32
+ def self.find_all(repo, ref, options = {})
33
+ allowed_options = [:max_count, :skip, :since]
34
+
35
+ default_options = {:numstat => true}
36
+ actual_options = default_options.merge(options)
37
+
38
+ if ref
39
+ output = repo.git.log(actual_options, ref)
40
+ else
41
+ output = repo.git.log(actual_options.merge(:all => true))
42
+ end
43
+
44
+ self.list_from_string(repo, output)
45
+ end
46
+
47
+ # Parse out commit information into an array of baked Commit objects
48
+ # +repo+ is the Repo
49
+ # +text+ is the text output from the git command (raw format)
50
+ #
51
+ # Returns assoc array [sha, Grit::Commit[] (baked)]
52
+ def self.list_from_string(repo, text)
53
+ lines = text.split("\n")
54
+
55
+ commits = []
56
+
57
+ while !lines.empty?
58
+ id = lines.shift.split.last
59
+
60
+ lines.shift
61
+ lines.shift
62
+ lines.shift
63
+
64
+ message_lines = []
65
+ message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/ || lines.first == ''
66
+
67
+ lines.shift while lines.first && lines.first.empty?
68
+
69
+ files = []
70
+ while lines.first =~ /^([-\d]+)\s+([-\d]+)\s+(.+)/
71
+ (additions, deletions, filename) = lines.shift.split
72
+ additions = additions.to_i
73
+ deletions = deletions.to_i
74
+ total = additions + deletions
75
+ files << [filename, additions, deletions, total]
76
+ end
77
+
78
+ lines.shift while lines.first && lines.first.empty?
79
+
80
+ commits << [id, CommitStats.new(repo, id, files)]
81
+ end
82
+
83
+ commits
84
+ end
85
+
86
+ # Pretty object inspection
87
+ def inspect
88
+ %Q{#<Grit::CommitStats "#{@id}">}
89
+ end
90
+
91
+ # Convert to an easy-to-traverse structure
92
+ def to_diffstat
93
+ files.map do |metadata|
94
+ DiffStat.new(*metadata)
95
+ end
96
+ end
97
+
98
+ # private
99
+
100
+ def to_hash
101
+ {
102
+ 'id' => id,
103
+ 'files' => files,
104
+ 'additions' => additions,
105
+ 'deletions' => deletions,
106
+ 'total' => total
107
+ }
108
+ end
109
+
110
+ end # CommitStats
111
+
112
+ class DiffStat
113
+ attr_reader :filename, :additions, :deletions
114
+
115
+ def initialize(filename, additions, deletions, total=nil)
116
+ @filename, @additions, @deletions = filename, additions, deletions
117
+ end
118
+
119
+ def net
120
+ additions - deletions
121
+ end
122
+
123
+ def inspect
124
+ "#{filename}: +#{additions} -#{deletions}"
125
+ end
126
+ end
127
+
128
+ end # Grit
@@ -0,0 +1,44 @@
1
+ module Grit
2
+
3
+ class Config
4
+ def initialize(repo)
5
+ @repo = repo
6
+ end
7
+
8
+ def []=(key, value)
9
+ @repo.git.config({}, key, value)
10
+ @data = nil
11
+ end
12
+
13
+ def [](key)
14
+ data[key]
15
+ end
16
+
17
+ def fetch(key, default = nil)
18
+ data[key] || default || raise(IndexError.new("key not found"))
19
+ end
20
+
21
+ def keys
22
+ data.keys
23
+ end
24
+
25
+ protected
26
+ def data
27
+ @data ||= load_config
28
+ end
29
+
30
+ def load_config
31
+ hash = {}
32
+ config_lines.map do |line|
33
+ key, value = line.split(/=/, 2)
34
+ hash[key] = value
35
+ end
36
+ hash
37
+ end
38
+
39
+ def config_lines
40
+ @repo.git.config(:list => true).split(/\n/)
41
+ end
42
+ end # Config
43
+
44
+ end # Grit