gifts 0.0.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 (56) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +29 -0
  5. data/Rakefile +9 -0
  6. data/gifts.gemspec +32 -0
  7. data/lib/gifts.rb +22 -0
  8. data/lib/gifts/commit_table.rb +70 -0
  9. data/lib/gifts/database.rb +49 -0
  10. data/lib/gifts/diff_table.rb +55 -0
  11. data/lib/gifts/file_table.rb +51 -0
  12. data/lib/gifts/repo_table.rb +31 -0
  13. data/lib/gifts/table_base.rb +18 -0
  14. data/lib/gifts/term_table.rb +28 -0
  15. data/lib/gifts/user_table.rb +19 -0
  16. data/lib/gifts/version.rb +3 -0
  17. data/spec/.gitkeeper +0 -0
  18. data/vendor/lib/LICENSE-grit +22 -0
  19. data/vendor/lib/LICENSE-grit_ext +22 -0
  20. data/vendor/lib/gifts/grit.rb +73 -0
  21. data/vendor/lib/gifts/grit/actor.rb +52 -0
  22. data/vendor/lib/gifts/grit/blame.rb +70 -0
  23. data/vendor/lib/gifts/grit/blob.rb +126 -0
  24. data/vendor/lib/gifts/grit/commit.rb +324 -0
  25. data/vendor/lib/gifts/grit/commit_stats.rb +128 -0
  26. data/vendor/lib/gifts/grit/config.rb +44 -0
  27. data/vendor/lib/gifts/grit/diff.rb +97 -0
  28. data/vendor/lib/gifts/grit/errors.rb +10 -0
  29. data/vendor/lib/gifts/grit/git-ruby.rb +262 -0
  30. data/vendor/lib/gifts/grit/git-ruby/commit_db.rb +52 -0
  31. data/vendor/lib/gifts/grit/git-ruby/git_object.rb +353 -0
  32. data/vendor/lib/gifts/grit/git-ruby/internal/file_window.rb +58 -0
  33. data/vendor/lib/gifts/grit/git-ruby/internal/loose.rb +137 -0
  34. data/vendor/lib/gifts/grit/git-ruby/internal/pack.rb +398 -0
  35. data/vendor/lib/gifts/grit/git-ruby/internal/raw_object.rb +44 -0
  36. data/vendor/lib/gifts/grit/git-ruby/repository.rb +784 -0
  37. data/vendor/lib/gifts/grit/git.rb +501 -0
  38. data/vendor/lib/gifts/grit/index.rb +222 -0
  39. data/vendor/lib/gifts/grit/lazy.rb +35 -0
  40. data/vendor/lib/gifts/grit/merge.rb +45 -0
  41. data/vendor/lib/gifts/grit/ref.rb +98 -0
  42. data/vendor/lib/gifts/grit/repo.rb +722 -0
  43. data/vendor/lib/gifts/grit/ruby1.9.rb +15 -0
  44. data/vendor/lib/gifts/grit/status.rb +153 -0
  45. data/vendor/lib/gifts/grit/submodule.rb +88 -0
  46. data/vendor/lib/gifts/grit/tag.rb +97 -0
  47. data/vendor/lib/gifts/grit/tree.rb +125 -0
  48. data/vendor/lib/gifts/grit_ext.rb +41 -0
  49. data/vendor/lib/gifts/grit_ext/actor.rb +15 -0
  50. data/vendor/lib/gifts/grit_ext/blob.rb +26 -0
  51. data/vendor/lib/gifts/grit_ext/commit.rb +15 -0
  52. data/vendor/lib/gifts/grit_ext/diff.rb +23 -0
  53. data/vendor/lib/gifts/grit_ext/tag.rb +10 -0
  54. data/vendor/lib/gifts/grit_ext/tree.rb +10 -0
  55. data/vendor/lib/gifts/grit_ext/version.rb +7 -0
  56. metadata +256 -0
@@ -0,0 +1,52 @@
1
+ begin
2
+ require 'sequel'
3
+
4
+ module Gifts::Grit
5
+
6
+ class CommitDb
7
+
8
+ SCHEMA_VERSION = 1
9
+
10
+ attr_accessor :db, :git
11
+
12
+ def initialize(git_obj, index_location = nil)
13
+ @git = git_obj
14
+ db_file = File.join(index_location || @git.git_dir, 'commit_db')
15
+ if !File.exists?(db_file)
16
+ @db = Sequel.open "sqlite:///#{db_file}"
17
+ setup_tables
18
+ else
19
+ @db = Sequel.open "sqlite:///#{db_file}"
20
+ end
21
+ end
22
+
23
+ def rev_list(branch, options)
24
+ end
25
+
26
+ def update_db(branch = nil)
27
+ # find all refs/heads, for each
28
+ # add branch if not there
29
+ # go though all commits in branch
30
+ # add new commit_branches a
31
+ # and commit_nodes for each new one
32
+ # stop if reach commit that already has branch and node links
33
+ end
34
+
35
+ def setup_tables
36
+ @db << "create table meta (meta_key text, meta_value text)"
37
+ @db[:meta] << {:meta_key => 'schema', :meta_value => SCHEMA_VERSION}
38
+
39
+ @db << "create table commits (id integer, sha text, author_date integer)"
40
+ @db << "create table nodes (id integer, path text, type text)"
41
+ @db << "create table branches (id integer, ref text, commit_id integer)"
42
+
43
+ @db << "create table commit_branches (commit_id integer, branch_id integer)"
44
+ @db << "create table commit_nodes (commit_id integer, node_id integer, node_sha string)"
45
+ end
46
+
47
+ end
48
+ end
49
+
50
+ rescue LoadError
51
+ # no commit db
52
+ end
@@ -0,0 +1,353 @@
1
+ #
2
+ # converted from the gitrb project
3
+ #
4
+ # authors:
5
+ # Matthias Lederhofer <matled@gmx.net>
6
+ # Simon 'corecode' Schubert <corecode@fs.ei.tum.de>
7
+ # Scott Chacon <schacon@gmail.com>
8
+ #
9
+ # provides native ruby access to git objects and pack files
10
+ #
11
+
12
+ # These classes translate the raw binary data kept in the sha encoded files
13
+ # into parsed data that can then be used in another fashion
14
+ require 'stringio'
15
+
16
+ module Gifts::Grit
17
+ module GitRuby
18
+
19
+ # class for author/committer/tagger lines
20
+ class UserInfo
21
+ attr_accessor :name, :email, :date, :offset
22
+
23
+ def initialize(str)
24
+ @email = ''
25
+ @date = Time.now
26
+ @offset = 0
27
+
28
+ m = /^(.*?) <(.*)> (\d+) ([+-])0*(\d+?)$/.match(str)
29
+ if !m
30
+ case str
31
+ when /<.+>/
32
+ m, @name, @email = *str.match(/(.*) <(.+?)>/)
33
+ else
34
+ @name = str
35
+ end
36
+ else
37
+ @name = m[1]
38
+ @email = m[2]
39
+ @date = Time.at(Integer(m[3]))
40
+ @offset = (m[4] == "-" ? -1 : 1)*Integer(m[5])
41
+ end
42
+ end
43
+
44
+ def to_s
45
+ "%s <%s> %s %+05d" % [@name, @email, @date.to_i, @offset]
46
+ end
47
+ end
48
+
49
+ # base class for all git objects (blob, tree, commit, tag)
50
+ class GitObject
51
+ attr_accessor :repository
52
+ attr_accessor :sha
53
+
54
+ def GitObject.from_raw(rawobject, repository = nil)
55
+ case rawobject.type
56
+ when :blob
57
+ return Blob.from_raw(rawobject, repository)
58
+ when :tree
59
+ return Tree.from_raw(rawobject, repository)
60
+ when :commit
61
+ return Commit.from_raw(rawobject, repository)
62
+ when :tag
63
+ return Tag.from_raw(rawobject, repository)
64
+ else
65
+ raise RuntimeError, "got invalid object-type"
66
+ end
67
+ end
68
+
69
+ def initialize
70
+ raise NotImplemented, "abstract class"
71
+ end
72
+
73
+ def type
74
+ raise NotImplemented, "abstract class"
75
+ end
76
+
77
+ def raw_content
78
+ raise NotImplemented, "abstract class"
79
+ end
80
+
81
+ def sha1
82
+ Digest::SHA1.hexdigest("%s %d\0" % \
83
+ [self.type, self.raw_content.length] + \
84
+ self.raw_content)
85
+ end
86
+ end
87
+
88
+ class Blob < GitObject
89
+ attr_accessor :content
90
+
91
+ def self.from_raw(rawobject, repository)
92
+ new(rawobject.content)
93
+ end
94
+
95
+ def initialize(content, repository=nil)
96
+ @content = content
97
+ @repository = repository
98
+ end
99
+
100
+ def type
101
+ :blob
102
+ end
103
+
104
+ def raw_content
105
+ @content
106
+ end
107
+ end
108
+
109
+ class DirectoryEntry
110
+ S_IFMT = 00170000
111
+ S_IFLNK = 0120000
112
+ S_IFREG = 0100000
113
+ S_IFDIR = 0040000
114
+ S_IFGITLINK = 0160000
115
+ attr_accessor :mode, :name, :sha1
116
+ def initialize(mode, filename, sha1o)
117
+ @mode = 0
118
+ mode.each_byte do |i|
119
+ @mode = (@mode << 3) | (i-'0'.getord(0))
120
+ end
121
+ @name = filename
122
+ @sha1 = sha1o
123
+ if ![S_IFLNK, S_IFDIR, S_IFREG, S_IFGITLINK].include?(@mode & S_IFMT)
124
+ raise RuntimeError, "unknown type for directory entry"
125
+ end
126
+ end
127
+
128
+ def type
129
+ case @mode & S_IFMT
130
+ when S_IFGITLINK
131
+ @type = :submodule
132
+ when S_IFLNK
133
+ @type = :link
134
+ when S_IFDIR
135
+ @type = :directory
136
+ when S_IFREG
137
+ @type = :file
138
+ else
139
+ raise RuntimeError, "unknown type for directory entry"
140
+ end
141
+ end
142
+
143
+ def type=(type)
144
+ case @type
145
+ when :link
146
+ @mode = (@mode & ~S_IFMT) | S_IFLNK
147
+ when :directory
148
+ @mode = (@mode & ~S_IFMT) | S_IFDIR
149
+ when :file
150
+ @mode = (@mode & ~S_IFMT) | S_IFREG
151
+ when :submodule
152
+ @mode = (@mode & ~S_IFMT) | S_IFGITLINK
153
+ else
154
+ raise RuntimeError, "invalid type"
155
+ end
156
+ end
157
+
158
+ def format_type
159
+ case type
160
+ when :link
161
+ 'link'
162
+ when :directory
163
+ 'tree'
164
+ when :file
165
+ 'blob'
166
+ when :submodule
167
+ 'commit'
168
+ end
169
+ end
170
+
171
+ def format_mode
172
+ "%06o" % @mode
173
+ end
174
+
175
+ def raw
176
+ "%o %s\0%s" % [@mode, @name, [@sha1].pack("H*")]
177
+ end
178
+ end
179
+
180
+
181
+ def self.read_bytes_until(io, char)
182
+ string = ''
183
+ if RUBY_VERSION > '1.9'
184
+ while ((next_char = io.getc) != char) && !io.eof
185
+ string += next_char
186
+ end
187
+ else
188
+ while ((next_char = io.getc.chr) != char) && !io.eof
189
+ string += next_char
190
+ end
191
+ end
192
+ string
193
+ end
194
+
195
+
196
+ class Tree < GitObject
197
+ attr_accessor :entry
198
+
199
+ def self.from_raw(rawobject, repository=nil)
200
+ raw = StringIO.new(rawobject.content)
201
+
202
+ entries = []
203
+ while !raw.eof?
204
+ mode = Gifts::Grit::GitRuby.read_bytes_until(raw, ' ')
205
+ file_name = Gifts::Grit::GitRuby.read_bytes_until(raw, "\0")
206
+ raw_sha = raw.read(20)
207
+ sha = raw_sha.unpack("H*").first
208
+
209
+ entries << DirectoryEntry.new(mode, file_name, sha)
210
+ end
211
+ new(entries, repository)
212
+ end
213
+
214
+ def initialize(entries=[], repository = nil)
215
+ @entry = entries
216
+ @repository = repository
217
+ end
218
+
219
+ def type
220
+ :tree
221
+ end
222
+
223
+ def raw_content
224
+ # TODO: sort correctly
225
+ #@entry.sort { |a,b| a.name <=> b.name }.
226
+ @entry.collect { |e| [[e.format_mode, e.format_type, e.sha1].join(' '), e.name].join("\t") }.join("\n")
227
+ end
228
+
229
+ def actual_raw
230
+ #@entry.collect { |e| e.raw.join(' '), e.name].join("\t") }.join("\n")
231
+ end
232
+ end
233
+
234
+ class Commit < GitObject
235
+ attr_accessor :author, :committer, :tree, :parent, :message, :headers
236
+
237
+ def self.from_raw(rawobject, repository=nil)
238
+ parent = []
239
+ tree = author = committer = nil
240
+
241
+ headers, message = rawobject.content.split(/\n\n/, 2)
242
+ all_headers = headers.split(/\n/).map { |header| header.split(/ /, 2) }
243
+ all_headers.each do |key, value|
244
+ case key
245
+ when "tree"
246
+ tree = value
247
+ when "parent"
248
+ parent.push(value)
249
+ when "author"
250
+ author = UserInfo.new(value)
251
+ when "committer"
252
+ committer = UserInfo.new(value)
253
+ else
254
+ warn "unknown header '%s' in commit %s" % \
255
+ [key, rawobject.sha1.unpack("H*")[0]]
256
+ end
257
+ end
258
+ if not tree && author && committer
259
+ raise RuntimeError, "incomplete raw commit object"
260
+ end
261
+ new(tree, parent, author, committer, message, headers, repository)
262
+ end
263
+
264
+ def initialize(tree, parent, author, committer, message, headers, repository=nil)
265
+ @tree = tree
266
+ @author = author
267
+ @parent = parent
268
+ @committer = committer
269
+ @message = message
270
+ @headers = headers
271
+ @repository = repository
272
+ end
273
+
274
+ def type
275
+ :commit
276
+ end
277
+
278
+ def raw_content
279
+ "tree %s\n%sauthor %s\ncommitter %s\n\n" % [
280
+ @tree,
281
+ @parent.collect { |i| "parent %s\n" % i }.join,
282
+ @author, @committer] + @message
283
+ end
284
+
285
+ def raw_log(sha)
286
+ output = "commit #{sha}\n"
287
+ output += @headers + "\n\n"
288
+ output += @message.split("\n").map { |l| ' ' + l }.join("\n") + "\n\n"
289
+ end
290
+
291
+ end
292
+
293
+ class Tag < GitObject
294
+ attr_accessor :object, :tag, :tagger, :message, :object_type
295
+ attr_writer :type
296
+
297
+ def self.from_raw(rawobject, repository=nil)
298
+
299
+ headers, message = rawobject.content.split(/\n\n/, 2)
300
+ headers = headers.split(/\n/).map { |header| header.split(' ', 2) }
301
+
302
+ object = ''
303
+ type = ''
304
+ tag = ''
305
+ tagger = ''
306
+
307
+ headers.each do |key, value|
308
+ case key
309
+ when "object"
310
+ object = value
311
+ when "type"
312
+ if !["blob", "tree", "commit", "tag"].include?(value)
313
+ raise RuntimeError, "invalid type in tag"
314
+ end
315
+ type = value.to_sym
316
+ when "tag"
317
+ tag = value
318
+ when "tagger"
319
+ tagger = UserInfo.new(value)
320
+ else
321
+ warn "unknown header '%s' in tag" % \
322
+ [key, rawobject.sha1.unpack("H*")[0]]
323
+ end
324
+ end
325
+
326
+ if not object && type && tag && tagger
327
+ raise RuntimeError, "incomplete raw tag object"
328
+ end
329
+ new(object, type, tag, tagger, message, repository)
330
+ end
331
+
332
+ def initialize(object, type, tag, tagger, message, repository=nil)
333
+ @object = object
334
+ @type = type
335
+ @object_type = type
336
+ @tag = tag
337
+ @tagger = tagger
338
+ @repository = repository
339
+ @message = message
340
+ end
341
+
342
+ def raw_content
343
+ ("object %s\ntype %s\ntag %s\ntagger %s\n\n" % \
344
+ [@object, @type, @tag, @tagger]) + @message.to_s
345
+ end
346
+
347
+ def type
348
+ :tag
349
+ end
350
+ end
351
+
352
+ end
353
+ end
@@ -0,0 +1,58 @@
1
+ #
2
+ # converted from the gitrb project
3
+ #
4
+ # authors:
5
+ # Matthias Lederhofer <matled@gmx.net>
6
+ # Simon 'corecode' Schubert <corecode@fs.ei.tum.de>
7
+ # Scott Chacon <schacon@gmail.com>
8
+ #
9
+ # provides native ruby access to git objects and pack files
10
+ #
11
+
12
+ module Gifts::Grit
13
+ module GitRuby
14
+ module Internal
15
+ class FileWindow
16
+ def initialize(file, version = 1)
17
+ @file = file
18
+ @offset = nil
19
+ if version == 2
20
+ @global_offset = 8
21
+ else
22
+ @global_offset = 0
23
+ end
24
+ end
25
+
26
+ def unmap
27
+ @file = nil
28
+ end
29
+
30
+ def [](*idx)
31
+ idx = idx[0] if idx.length == 1
32
+ case idx
33
+ when Range
34
+ offset = idx.first
35
+ len = idx.last - idx.first + idx.exclude_end? ? 0 : 1
36
+ when Fixnum
37
+ offset = idx
38
+ len = nil
39
+ when Array
40
+ offset, len = idx
41
+ else
42
+ raise RuntimeError, "invalid index param: #{idx.class}"
43
+ end
44
+ if @offset != offset
45
+ @file.seek(offset + @global_offset)
46
+ end
47
+ @offset = offset + len ? len : 1
48
+ if not len
49
+ @file.read(1).getord(0)
50
+ else
51
+ @file.read(len)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+