smeagol 0.6.0 → 0.6.1

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.
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