schacon-grit 0.9.1 → 0.9.3

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.
data/Manifest.txt CHANGED
@@ -3,7 +3,6 @@ Manifest.txt
3
3
  README.txt
4
4
  Rakefile
5
5
  grit.gemspec
6
- lib/grit.rb
7
6
  lib/grit/actor.rb
8
7
  lib/grit/blob.rb
9
8
  lib/grit/commit.rb
@@ -11,12 +10,26 @@ lib/grit/commit_stats.rb
11
10
  lib/grit/config.rb
12
11
  lib/grit/diff.rb
13
12
  lib/grit/errors.rb
13
+ lib/grit/git-ruby/commit_db.rb
14
+ lib/grit/git-ruby/file_index.rb
15
+ lib/grit/git-ruby/git_object.rb
16
+ lib/grit/git-ruby/internal/loose.rb
17
+ lib/grit/git-ruby/internal/mmap.rb
18
+ lib/grit/git-ruby/internal/pack.rb
19
+ lib/grit/git-ruby/internal/raw_object.rb
20
+ lib/grit/git-ruby/object.rb
21
+ lib/grit/git-ruby/repository.rb
22
+ lib/grit/git-ruby.rb
14
23
  lib/grit/git.rb
24
+ lib/grit/head.rb
15
25
  lib/grit/index.rb
16
26
  lib/grit/lazy.rb
17
27
  lib/grit/ref.rb
18
28
  lib/grit/repo.rb
29
+ lib/grit/status.rb
30
+ lib/grit/tag.rb
19
31
  lib/grit/tree.rb
32
+ lib/grit.rb
20
33
  test/fixtures/blame
21
34
  test/fixtures/cat_file_blob
22
35
  test/fixtures/cat_file_blob_size
data/grit.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "grit"
3
- s.version = "0.9.1"
3
+ s.version = "0.9.3"
4
4
  s.date = "2008-04-24"
5
5
  s.summary = "Object model interface to a git repo"
6
6
  s.email = "tom@rubyisawesome.com"
@@ -56,5 +56,7 @@ Gem::Specification.new do |s|
56
56
  "test/test_tree.rb"]
57
57
  s.rdoc_options = ["--main", "README.txt"]
58
58
  s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
59
+ s.add_dependency("diff-lcs", ["> 0.0.0"])
59
60
  s.add_dependency("mime-types", ["> 0.0.0"])
61
+ s.add_dependency("open4", ["> 0.0.0"])
60
62
  end
data/lib/grit/commit.rb CHANGED
@@ -182,6 +182,14 @@ module Grit
182
182
  def to_s
183
183
  @id
184
184
  end
185
+
186
+ def sha
187
+ @id
188
+ end
189
+
190
+ def date
191
+ @committed_date
192
+ end
185
193
 
186
194
  # Pretty object inspection
187
195
  def inspect
data/lib/grit/git-ruby.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'grit/git-ruby/repository'
2
2
  require 'grit/git-ruby/file_index'
3
- require 'grit/git-ruby/commit_db'
4
3
 
5
4
  module Grit
6
5
 
@@ -11,6 +10,14 @@ module Grit
11
10
 
12
11
  attr_accessor :ruby_git_repo, :git_file_index
13
12
 
13
+ def init(options)
14
+ if options.size == 0
15
+ Grit::GitRuby::Repository.init(@git_dir)
16
+ else
17
+ method_missing('init', options)
18
+ end
19
+ end
20
+
14
21
  def cat_file(options, ref)
15
22
  if options[:t]
16
23
  file_type(ref)
@@ -172,4 +179,4 @@ module Grit
172
179
  # git log --pretty='raw' --max-count='1' 'master' -- 'test'
173
180
 
174
181
  end
175
- end
182
+ end
@@ -9,17 +9,18 @@
9
9
  # provides native ruby access to git objects and pack files
10
10
  #
11
11
 
12
- begin
13
- require 'mmap'
14
- rescue LoadError
15
-
16
12
  module Grit
17
13
  module GitRuby
18
14
  module Internal
19
15
  class Mmap
20
- def initialize(file)
16
+ def initialize(file, version = 1)
21
17
  @file = file
22
18
  @offset = nil
19
+ if version == 2
20
+ @global_offset = 8
21
+ else
22
+ @global_offset = 0
23
+ end
23
24
  end
24
25
 
25
26
  def unmap
@@ -41,7 +42,7 @@ module Grit
41
42
  raise RuntimeError, "invalid index param: #{idx.class}"
42
43
  end
43
44
  if @offset != offset
44
- @file.seek(offset)
45
+ @file.seek(offset + @global_offset)
45
46
  end
46
47
  @offset = offset + len ? len : 1
47
48
  if not len
@@ -55,5 +56,3 @@ module Grit
55
56
  end
56
57
  end
57
58
 
58
- end # rescue LoadError
59
-
@@ -13,6 +13,9 @@ require 'zlib'
13
13
  require 'grit/git-ruby/internal/raw_object'
14
14
  require 'grit/git-ruby/internal/mmap'
15
15
 
16
+ PACK_SIGNATURE = "PACK"
17
+ PACK_IDX_SIGNATURE = "\377tOc"
18
+
16
19
  module Grit
17
20
  module GitRuby
18
21
  module Internal
@@ -27,30 +30,19 @@ module Grit
27
30
  SHA1Size = 20
28
31
  IdxOffsetSize = 4
29
32
  OffsetSize = 4
33
+ CrcSize = 4
30
34
  OffsetStart = FanOutCount * IdxOffsetSize
31
35
  SHA1Start = OffsetStart + OffsetSize
32
36
  EntrySize = OffsetSize + SHA1Size
37
+ EntrySizeV2 = SHA1Size + CrcSize + OffsetSize
33
38
 
34
39
  def initialize(file)
35
40
  if file =~ /\.idx$/
36
41
  file = file[0...-3] + 'pack'
37
42
  end
38
-
39
- @cache = {}
40
43
  @name = file
41
-
42
- with_idx do |idx|
43
- @offsets = [0]
44
- FanOutCount.times do |i|
45
- pos = idx[i * IdxOffsetSize,IdxOffsetSize].unpack('N')[0]
46
- if pos < @offsets[i]
47
- raise PackFormatError, "pack #@name has discontinuous index #{i}"
48
- end
49
- @offsets << pos
50
- end
51
-
52
- @size = @offsets[-1]
53
- end
44
+ @cache = {}
45
+ init_pack
54
46
  end
55
47
 
56
48
  def with_idx(index_file = nil)
@@ -60,7 +52,21 @@ module Grit
60
52
  else
61
53
  idxfile = File.open(index_file)
62
54
  end
63
- idx = Mmap.new(idxfile)
55
+
56
+ # read header
57
+ sig = idxfile.read(4)
58
+ ver = idxfile.read(4).unpack("N")[0]
59
+
60
+ if sig == PACK_IDX_SIGNATURE
61
+ if(ver != 2)
62
+ raise PackFormatError, "pack #@name has unknown pack file version #{ver}"
63
+ end
64
+ @version = 2
65
+ else
66
+ @version = 1
67
+ end
68
+
69
+ idx = Mmap.new(idxfile, @version)
64
70
  yield idx
65
71
  idx.unmap
66
72
  idxfile.close
@@ -72,31 +78,6 @@ module Grit
72
78
  packfile.close
73
79
  end
74
80
 
75
- # given an index file, list out the shas that it's packfile contains
76
- def self.get_shas(index_file)
77
- with_idx(index_file) do |idx|
78
- @offsets = [0]
79
- FanOutCount.times do |i|
80
- pos = idx[i * IdxOffsetSize,IdxOffsetSize].unpack('N')[0]
81
- if pos < @offsets[i]
82
- raise PackFormatError, "pack #@name has discontinuous index #{i}"
83
- end
84
- @offsets << pos
85
- end
86
-
87
- @size = @offsets[-1]
88
- shas = []
89
-
90
- pos = SHA1Start
91
- @size.times do
92
- sha1 = idx[pos,SHA1Size]
93
- pos += EntrySize
94
- shas << sha1.unpack("H*").first
95
- end
96
- shas
97
- end
98
- end
99
-
100
81
  def cache_objects
101
82
  @cache = {}
102
83
  with_packfile do |packfile|
@@ -117,6 +98,13 @@ module Grit
117
98
  # shouldnt be anything open now
118
99
  end
119
100
 
101
+ # given an index file, list out the shas that it's packfile contains
102
+ def get_shas
103
+ shas = []
104
+ each_sha1 { |sha| shas << sha.unpack("H*")[0] }
105
+ shas
106
+ end
107
+
120
108
  def [](sha1)
121
109
  if obj = @cache[sha1]
122
110
  return obj
@@ -128,39 +116,77 @@ module Grit
128
116
  return obj
129
117
  end
130
118
 
131
- def each_entry
119
+ def init_pack
132
120
  with_idx do |idx|
133
- pos = OffsetStart
134
- @size.times do
135
- offset = idx[pos,OffsetSize].unpack('N')[0]
136
- sha1 = idx[pos+OffsetSize,SHA1Size]
137
- pos += EntrySize
138
- yield sha1, offset
121
+ @offsets = [0]
122
+ FanOutCount.times do |i|
123
+ pos = idx[i * IdxOffsetSize,IdxOffsetSize].unpack('N')[0]
124
+ if pos < @offsets[i]
125
+ raise PackFormatError, "pack #@name has discontinuous index #{i}"
126
+ end
127
+ @offsets << pos
139
128
  end
129
+ @size = @offsets[-1]
140
130
  end
141
131
  end
142
-
143
- def each_sha1
132
+
133
+ def each_entry
144
134
  with_idx do |idx|
145
- # unpacking the offset is quite expensive, so
146
- # we avoid using #each
147
- pos = SHA1Start
148
- @size.times do
149
- sha1 = idx[pos,SHA1Size]
150
- pos += EntrySize
151
- yield sha1
135
+ if @version == 2
136
+ data = read_data_v2(idx)
137
+ data.each do |sha1, crc, offset|
138
+ yield sha1, offset
139
+ end
140
+ else
141
+ pos = OffsetStart
142
+ @size.times do
143
+ offset = idx[pos,OffsetSize].unpack('N')[0]
144
+ sha1 = idx[pos+OffsetSize,SHA1Size]
145
+ pos += EntrySize
146
+ yield sha1, offset
147
+ end
152
148
  end
153
149
  end
154
150
  end
155
-
156
- def find_object(sha1)
157
- obj = nil
151
+
152
+ def read_data_v2(idx)
153
+ data = []
154
+ pos = OffsetStart
155
+ @size.times do |i|
156
+ data[i] = [idx[pos,SHA1Size], 0, 0]
157
+ pos += SHA1Size
158
+ end
159
+ @size.times do |i|
160
+ crc = idx[pos,CrcSize]
161
+ data[i][1] = crc
162
+ pos += CrcSize
163
+ end
164
+ @size.times do |i|
165
+ offset = idx[pos,OffsetSize].unpack('N')[0]
166
+ data[i][2] = offset
167
+ pos += OffsetSize
168
+ end
169
+ data
170
+ end
171
+ private :read_data_v2
172
+
173
+ def each_sha1
158
174
  with_idx do |idx|
159
- obj = find_object_in_index(idx, sha1)
175
+ if @version == 2
176
+ data = read_data_v2(idx)
177
+ data.each do |sha1, crc, offset|
178
+ yield sha1
179
+ end
180
+ else
181
+ pos = SHA1Start
182
+ @size.times do
183
+ sha1 = idx[pos,SHA1Size]
184
+ pos += EntrySize
185
+ yield sha1
186
+ end
187
+ end
160
188
  end
161
- obj
162
- end
163
- private :find_object
189
+ end
164
190
 
165
191
  def find_object_in_index(idx, sha1)
166
192
  slot = sha1[0]
@@ -168,22 +194,46 @@ module Grit
168
194
  first, last = @offsets[slot,2]
169
195
  while first < last
170
196
  mid = (first + last) / 2
171
- midsha1 = idx[SHA1Start + mid * EntrySize,SHA1Size]
172
- cmp = midsha1 <=> sha1
197
+ if @version == 2
198
+ midsha1 = idx[OffsetStart + (mid * SHA1Size), SHA1Size]
199
+ cmp = midsha1 <=> sha1
173
200
 
174
- if cmp < 0
175
- first = mid + 1
176
- elsif cmp > 0
177
- last = mid
201
+ if cmp < 0
202
+ first = mid + 1
203
+ elsif cmp > 0
204
+ last = mid
205
+ else
206
+ pos = OffsetStart + (@size * (SHA1Size + CrcSize)) + (mid * OffsetSize)
207
+ offset = idx[pos, OffsetSize].unpack('N')[0]
208
+ return offset
209
+ end
178
210
  else
179
- pos = OffsetStart + mid * EntrySize
180
- offset = idx[pos,OffsetSize].unpack('N')[0]
181
- return offset
211
+ midsha1 = idx[SHA1Start + mid * EntrySize,SHA1Size]
212
+ cmp = midsha1 <=> sha1
213
+
214
+ if cmp < 0
215
+ first = mid + 1
216
+ elsif cmp > 0
217
+ last = mid
218
+ else
219
+ pos = OffsetStart + mid * EntrySize
220
+ offset = idx[pos,OffsetSize].unpack('N')[0]
221
+ return offset
222
+ end
182
223
  end
183
224
  end
184
225
  nil
185
226
  end
186
-
227
+
228
+ def find_object(sha1)
229
+ obj = nil
230
+ with_idx do |idx|
231
+ obj = find_object_in_index(idx, sha1)
232
+ end
233
+ obj
234
+ end
235
+ private :find_object
236
+
187
237
  def parse_object(offset)
188
238
  obj = nil
189
239
  with_packfile do |packfile|
@@ -37,6 +37,7 @@ module Grit
37
37
  def initialize(git_dir, options = {})
38
38
  @git_dir = git_dir
39
39
  @options = options
40
+ @packs = []
40
41
  end
41
42
 
42
43
  # returns the loose objects object lazily
@@ -599,6 +600,53 @@ module Grit
599
600
  found_data
600
601
  end
601
602
 
603
+ # initialize a git repository
604
+ def self.init(dir, bare = false)
605
+
606
+ FileUtils.mkdir_p(dir) if !File.exists?(dir)
607
+
608
+ FileUtils.cd(dir) do
609
+ if(File.exists?('objects'))
610
+ return false # already initialized
611
+ else
612
+ # initialize directory
613
+ create_initial_config(bare)
614
+ FileUtils.mkdir_p('refs/heads')
615
+ FileUtils.mkdir_p('refs/tags')
616
+ FileUtils.mkdir_p('objects/info')
617
+ FileUtils.mkdir_p('objects/pack')
618
+ FileUtils.mkdir_p('branches')
619
+ add_file('description', 'Unnamed repository; edit this file to name it for gitweb.')
620
+ add_file('HEAD', "ref: refs/heads/master\n")
621
+ FileUtils.mkdir_p('hooks')
622
+ FileUtils.cd('hooks') do
623
+ add_file('applypatch-msg', '# add shell script and make executable to enable')
624
+ add_file('post-commit', '# add shell script and make executable to enable')
625
+ add_file('post-receive', '# add shell script and make executable to enable')
626
+ add_file('post-update', '# add shell script and make executable to enable')
627
+ add_file('pre-applypatch', '# add shell script and make executable to enable')
628
+ add_file('pre-commit', '# add shell script and make executable to enable')
629
+ add_file('pre-rebase', '# add shell script and make executable to enable')
630
+ add_file('update', '# add shell script and make executable to enable')
631
+ end
632
+ FileUtils.mkdir_p('info')
633
+ add_file('info/exclude', "# *.[oa]\n# *~")
634
+ end
635
+ end
636
+ end
637
+
638
+ def self.create_initial_config(bare = false)
639
+ bare ? bare_status = 'true' : bare_status = 'false'
640
+ config = "[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = #{bare_status}\n\tlogallrefupdates = true"
641
+ add_file('config', config)
642
+ end
643
+
644
+ def self.add_file(name, contents)
645
+ File.open(name, 'w') do |f|
646
+ f.write contents
647
+ end
648
+ end
649
+
602
650
  def close
603
651
  @packs.each do |pack|
604
652
  pack.close
@@ -625,6 +673,9 @@ module Grit
625
673
  alt = File.join(path, 'info/alternates')
626
674
  if File.exists?(alt)
627
675
  File.readlines(alt).each do |line|
676
+ if line[0, 2] == '..'
677
+ line = File.expand_path(File.join(@git_dir, line))
678
+ end
628
679
  load_loose(line.chomp)
629
680
  load_alternate_loose(line.chomp)
630
681
  end
@@ -648,6 +699,9 @@ module Grit
648
699
  alt = File.join(path, 'info/alternates')
649
700
  if File.exists?(alt)
650
701
  File.readlines(alt).each do |line|
702
+ if line[0, 2] == '..'
703
+ line = File.expand_path(File.join(@git_dir, line))
704
+ end
651
705
  full_pack = File.join(line.chomp, 'pack')
652
706
  load_packs(full_pack)
653
707
  load_alternate_packs(File.join(line.chomp))
data/lib/grit/index.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  module Grit
2
2
 
3
3
  class Index
4
- attr_accessor :repo, :tree
4
+ attr_accessor :repo, :tree, :current_tree
5
5
 
6
6
  def initialize(repo)
7
7
  self.repo = repo
8
8
  self.tree = {}
9
+ self.current_tree = nil
9
10
  end
10
11
 
11
12
  # Add a file to the index
@@ -28,12 +29,16 @@ module Grit
28
29
  current[filename] = data
29
30
  end
30
31
 
32
+ def read_tree(tree)
33
+ self.current_tree = self.repo.tree(tree)
34
+ end
35
+
31
36
  # Commit the contents of the index
32
37
  # +message+ is the commit message
33
38
  #
34
39
  # Returns a String of the SHA1 of the commit
35
- def commit(message, parents = nil, actor = nil, last_tree = nil)
36
- tree_sha1 = write_tree(self.tree)
40
+ def commit(message, parents = nil, actor = nil, last_tree = nil, head = 'master')
41
+ tree_sha1 = write_tree(self.tree, self.current_tree)
37
42
  return false if tree_sha1 == last_tree # don't write identical commits
38
43
 
39
44
  contents = []
@@ -60,7 +65,7 @@ module Grit
60
65
  commit_sha1 = self.repo.git.ruby_git.put_raw_object(contents.join("\n"), 'commit')
61
66
 
62
67
  # self.repo.git.update_ref({}, 'HEAD', commit_sha1)
63
- File.open(File.join(self.repo.path, 'refs', 'heads', 'master'), 'w') do |f|
68
+ File.open(File.join(self.repo.path, 'refs', 'heads', head), 'w') do |f|
64
69
  f.write(commit_sha1)
65
70
  end if commit_sha1
66
71
 
@@ -71,23 +76,35 @@ module Grit
71
76
  # +tree+ is the tree
72
77
  #
73
78
  # Returns the SHA1 String of the tree
74
- def write_tree(tree)
75
- tree_contents = ''
79
+ def write_tree(tree, now_tree = nil)
80
+ tree_contents = {}
81
+
82
+ # fill in original tree
83
+ now_tree.contents.each do |obj|
84
+ sha = [obj.id].pack("H*")
85
+ k = obj.name
86
+ k += '/' if (obj.class == Grit::Tree)
87
+ tree_contents[k] = "%s %s\0%s" % [obj.mode.to_s, obj.name, sha]
88
+ end if now_tree
89
+
90
+ # overwrite with new tree contents
76
91
  tree.each do |k, v|
77
92
  case v
78
93
  when String:
79
94
  sha = write_blob(v)
80
95
  sha = [sha].pack("H*")
81
96
  str = "%s %s\0%s" % ['100644', k, sha]
82
- tree_contents += str
97
+ tree_contents[k] = str
83
98
  when Hash:
84
- sha = write_tree(v)
99
+ ctree = now_tree/k if now_tree
100
+ sha = write_tree(v, ctree)
85
101
  sha = [sha].pack("H*")
86
102
  str = "%s %s\0%s" % ['040000', k, sha]
87
- tree_contents += str
103
+ tree_contents[k + '/'] = str
88
104
  end
89
105
  end
90
- self.repo.git.ruby_git.put_raw_object(tree_contents, 'tree')
106
+ tr = tree_contents.sort.map { |k, v| v }.join('')
107
+ self.repo.git.ruby_git.put_raw_object(tr, 'tree')
91
108
  end
92
109
 
93
110
  # Write the blob to the index
data/lib/grit/repo.rb CHANGED
@@ -5,6 +5,7 @@ module Grit
5
5
 
6
6
  # The path of the git repo as a String
7
7
  attr_accessor :path
8
+ attr_accessor :working_dir
8
9
  attr_reader :bare
9
10
 
10
11
  # The git command line interface object
@@ -22,6 +23,7 @@ module Grit
22
23
  epath = File.expand_path(path)
23
24
 
24
25
  if File.exist?(File.join(epath, '.git'))
26
+ self.working_dir = epath
25
27
  self.path = File.join(epath, '.git')
26
28
  @bare = false
27
29
  elsif File.exist?(epath) && (epath =~ /\.git$/ || options[:is_bare])
@@ -60,6 +62,10 @@ module Grit
60
62
 
61
63
  alias_method :branches, :heads
62
64
 
65
+ def is_head?(head_name)
66
+ heads.find { |h| h.name == head_name }
67
+ end
68
+
63
69
  # Object reprsenting the current repo head.
64
70
  #
65
71
  # Returns Grit::Head (baked)
data/lib/grit/status.rb CHANGED
@@ -88,25 +88,27 @@ module Grit
88
88
  def construct_status
89
89
  @files = ls_files
90
90
 
91
- # find untracked in working dir
92
- Dir.glob('**/*') do |file|
93
- if !@files[file]
94
- @files[file] = {:path => file, :untracked => true} if !File.directory?(file)
91
+ Dir.chdir(@base.working_dir) do
92
+ # find untracked in working dir
93
+ Dir.glob('**/*') do |file|
94
+ if !@files[file]
95
+ @files[file] = {:path => file, :untracked => true} if !File.directory?(file)
96
+ end
95
97
  end
96
- end
97
98
 
98
- # find modified in tree
99
- diff_files.each do |path, data|
100
- @files[path] ? @files[path].merge!(data) : @files[path] = data
101
- end
99
+ # find modified in tree
100
+ diff_files.each do |path, data|
101
+ @files[path] ? @files[path].merge!(data) : @files[path] = data
102
+ end
102
103
 
103
- # find added but not committed - new files
104
- diff_index('HEAD').each do |path, data|
105
- @files[path] ? @files[path].merge!(data) : @files[path] = data
106
- end
104
+ # find added but not committed - new files
105
+ diff_index('HEAD').each do |path, data|
106
+ @files[path] ? @files[path].merge!(data) : @files[path] = data
107
+ end
107
108
 
108
- @files.each do |k, file_hash|
109
- @files[k] = StatusFile.new(@base, file_hash)
109
+ @files.each do |k, file_hash|
110
+ @files[k] = StatusFile.new(@base, file_hash)
111
+ end
110
112
  end
111
113
  end
112
114
 
data/test/test_head.rb CHANGED
@@ -28,6 +28,12 @@ class TestHead < Test::Unit::TestCase
28
28
  head = @r.heads[2]
29
29
  assert_equal %Q{#<Grit::Head "test/chacon">}, head.inspect
30
30
  end
31
+
32
+ def test_is_head
33
+ assert @r.is_head?('master')
34
+ assert @r.is_head?('test/chacon')
35
+ assert !@r.is_head?('masterblah')
36
+ end
31
37
 
32
38
  def test_head_count
33
39
  assert_equal 5, @r.heads.size
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schacon-grit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Preston-Werner
@@ -13,6 +13,15 @@ cert_chain: []
13
13
  date: 2008-04-24 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: diff-lcs
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
16
25
  - !ruby/object:Gem::Dependency
17
26
  name: mime-types
18
27
  version_requirement:
@@ -22,6 +31,15 @@ dependencies:
22
31
  - !ruby/object:Gem::Version
23
32
  version: 0.0.0
24
33
  version:
34
+ - !ruby/object:Gem::Dependency
35
+ name: open4
36
+ version_requirement:
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">"
40
+ - !ruby/object:Gem::Version
41
+ version: 0.0.0
42
+ version:
25
43
  description: Grit is a Ruby library for extracting information from a git repository in and object oriented manner.
26
44
  email: tom@rubyisawesome.com
27
45
  executables: []