schacon-grit 0.9.4 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/API.txt +101 -0
- data/History.txt +42 -2
- data/LICENSE +22 -0
- data/README.md +210 -0
- data/VERSION.yml +4 -0
- data/lib/grit.rb +17 -5
- data/lib/grit/blame.rb +61 -0
- data/lib/grit/blob.rb +11 -2
- data/lib/grit/commit.rb +44 -31
- data/lib/grit/commit_stats.rb +26 -2
- data/lib/grit/diff.rb +8 -8
- data/lib/grit/git-ruby.rb +87 -6
- data/lib/grit/git-ruby/git_object.rb +29 -6
- data/lib/grit/git-ruby/internal/{mmap.rb → file_window.rb} +2 -2
- data/lib/grit/git-ruby/internal/loose.rb +6 -6
- data/lib/grit/git-ruby/internal/pack.rb +22 -20
- data/lib/grit/git-ruby/object.rb +8 -2
- data/lib/grit/git-ruby/repository.rb +33 -24
- data/lib/grit/git.rb +189 -11
- data/lib/grit/index.rb +15 -14
- data/lib/grit/merge.rb +45 -0
- data/lib/grit/ref.rb +8 -29
- data/lib/grit/repo.rb +144 -21
- data/lib/grit/ruby1.9.rb +7 -0
- data/lib/grit/submodule.rb +5 -1
- data/lib/grit/tag.rb +22 -66
- data/lib/grit/tree.rb +20 -1
- metadata +32 -47
- data/Manifest.txt +0 -71
- data/README.txt +0 -213
- data/Rakefile +0 -29
- data/grit.gemspec +0 -62
- data/lib/grit/head.rb +0 -83
- data/test/test_actor.rb +0 -35
- data/test/test_blob.rb +0 -79
- data/test/test_commit.rb +0 -190
- data/test/test_config.rb +0 -58
- data/test/test_diff.rb +0 -18
- data/test/test_git.rb +0 -64
- data/test/test_grit.rb +0 -32
- data/test/test_head.rb +0 -47
- data/test/test_real.rb +0 -19
- data/test/test_reality.rb +0 -17
- data/test/test_remote.rb +0 -14
- data/test/test_repo.rb +0 -285
- data/test/test_tag.rb +0 -25
- data/test/test_tree.rb +0 -96
@@ -115,7 +115,7 @@ module Grit
|
|
115
115
|
def initialize(mode, filename, sha1o)
|
116
116
|
@mode = 0
|
117
117
|
mode.each_byte do |i|
|
118
|
-
@mode = (@mode << 3) | (i-'0'
|
118
|
+
@mode = (@mode << 3) | (i-'0'.getord(0))
|
119
119
|
end
|
120
120
|
@name = filename
|
121
121
|
@sha1 = sha1o
|
@@ -179,8 +179,14 @@ module Grit
|
|
179
179
|
|
180
180
|
def self.read_bytes_until(io, char)
|
181
181
|
string = ''
|
182
|
-
|
183
|
-
|
182
|
+
if RUBY_VERSION > '1.9'
|
183
|
+
while ((next_char = io.getc) != char) && !io.eof
|
184
|
+
string += next_char
|
185
|
+
end
|
186
|
+
else
|
187
|
+
while ((next_char = io.getc.chr) != char) && !io.eof
|
188
|
+
string += next_char
|
189
|
+
end
|
184
190
|
end
|
185
191
|
string
|
186
192
|
end
|
@@ -219,6 +225,16 @@ module Grit
|
|
219
225
|
@entry.collect { |e| [[e.format_mode, e.format_type, e.sha1].join(' '), e.name].join("\t") }.join("\n")
|
220
226
|
end
|
221
227
|
|
228
|
+
def to_hash
|
229
|
+
hash = {}
|
230
|
+
@entry.each do |e|
|
231
|
+
hash[e.name] = { 'mode' => e.format_mode,
|
232
|
+
'type' => e.format_type,
|
233
|
+
'sha' => e.sha1 }
|
234
|
+
end
|
235
|
+
hash
|
236
|
+
end
|
237
|
+
|
222
238
|
def actual_raw
|
223
239
|
#@entry.collect { |e| e.raw.join(' '), e.name].join("\t") }.join("\n")
|
224
240
|
end
|
@@ -243,9 +259,6 @@ module Grit
|
|
243
259
|
author = UserInfo.new(value)
|
244
260
|
when "committer"
|
245
261
|
committer = UserInfo.new(value)
|
246
|
-
else
|
247
|
-
warn "unknown header '%s' in commit %s" % \
|
248
|
-
[key, rawobject.sha1.unpack("H*")[0]]
|
249
262
|
end
|
250
263
|
end
|
251
264
|
if not tree && author && committer
|
@@ -281,6 +294,16 @@ module Grit
|
|
281
294
|
output += @message.split("\n").map { |l| ' ' + l }.join("\n") + "\n\n"
|
282
295
|
end
|
283
296
|
|
297
|
+
def to_hash
|
298
|
+
h = {}
|
299
|
+
h['tree'] = @tree
|
300
|
+
h['author'] = @author
|
301
|
+
h['committer'] = @committer
|
302
|
+
h['message'] = @message
|
303
|
+
h['parents'] = @parent
|
304
|
+
h
|
305
|
+
end
|
306
|
+
|
284
307
|
end
|
285
308
|
|
286
309
|
class Tag < GitObject
|
@@ -12,7 +12,7 @@
|
|
12
12
|
module Grit
|
13
13
|
module GitRuby
|
14
14
|
module Internal
|
15
|
-
class
|
15
|
+
class FileWindow
|
16
16
|
def initialize(file, version = 1)
|
17
17
|
@file = file
|
18
18
|
@offset = nil
|
@@ -46,7 +46,7 @@ module Grit
|
|
46
46
|
end
|
47
47
|
@offset = offset + len ? len : 1
|
48
48
|
if not len
|
49
|
-
@file.read(1)
|
49
|
+
@file.read(1).getord(0)
|
50
50
|
else
|
51
51
|
@file.read(len)
|
52
52
|
end
|
@@ -29,7 +29,7 @@ module Grit
|
|
29
29
|
begin
|
30
30
|
return nil unless sha1[0...2] && sha1[2..39]
|
31
31
|
path = @directory + '/' + sha1[0...2] + '/' + sha1[2..39]
|
32
|
-
get_raw_object(File.
|
32
|
+
get_raw_object(File.open(path, 'rb').read)
|
33
33
|
rescue Errno::ENOENT
|
34
34
|
nil
|
35
35
|
end
|
@@ -76,7 +76,7 @@ module Grit
|
|
76
76
|
content = Zlib::Deflate.deflate(store)
|
77
77
|
|
78
78
|
FileUtils.mkdir_p(@directory+'/'+sha1[0...2])
|
79
|
-
File.open(path, '
|
79
|
+
File.open(path, 'wb') do |f|
|
80
80
|
f.write content
|
81
81
|
end
|
82
82
|
end
|
@@ -102,7 +102,7 @@ module Grit
|
|
102
102
|
# private
|
103
103
|
def unpack_object_header_gently(buf)
|
104
104
|
used = 0
|
105
|
-
c = buf
|
105
|
+
c = buf.getord(used)
|
106
106
|
used += 1
|
107
107
|
|
108
108
|
type = (c >> 4) & 7;
|
@@ -112,7 +112,7 @@ module Grit
|
|
112
112
|
if buf.length <= used
|
113
113
|
raise LooseObjectError, "object file too short"
|
114
114
|
end
|
115
|
-
c = buf
|
115
|
+
c = buf.getord(used)
|
116
116
|
used += 1
|
117
117
|
|
118
118
|
size += (c & 0x7f) << shift
|
@@ -127,8 +127,8 @@ module Grit
|
|
127
127
|
private :unpack_object_header_gently
|
128
128
|
|
129
129
|
def legacy_loose_object?(buf)
|
130
|
-
word = (buf
|
131
|
-
buf
|
130
|
+
word = (buf.getord(0) << 8) + buf.getord(1)
|
131
|
+
buf.getord(0) == 0x78 && word % 31 == 0
|
132
132
|
end
|
133
133
|
private :legacy_loose_object?
|
134
134
|
end
|
@@ -11,7 +11,7 @@
|
|
11
11
|
|
12
12
|
require 'zlib'
|
13
13
|
require 'grit/git-ruby/internal/raw_object'
|
14
|
-
require 'grit/git-ruby/internal/
|
14
|
+
require 'grit/git-ruby/internal/file_window'
|
15
15
|
|
16
16
|
PACK_SIGNATURE = "PACK"
|
17
17
|
PACK_IDX_SIGNATURE = "\377tOc"
|
@@ -36,6 +36,8 @@ module Grit
|
|
36
36
|
EntrySize = OffsetSize + SHA1Size
|
37
37
|
EntrySizeV2 = SHA1Size + CrcSize + OffsetSize
|
38
38
|
|
39
|
+
attr_reader :size, :name
|
40
|
+
|
39
41
|
def initialize(file)
|
40
42
|
if file =~ /\.idx$/
|
41
43
|
file = file[0...-3] + 'pack'
|
@@ -48,9 +50,9 @@ module Grit
|
|
48
50
|
def with_idx(index_file = nil)
|
49
51
|
if !index_file
|
50
52
|
index_file = @name
|
51
|
-
idxfile = File.open(@name[0...-4]+'idx')
|
53
|
+
idxfile = File.open(@name[0...-4]+'idx', 'rb')
|
52
54
|
else
|
53
|
-
idxfile = File.open(index_file)
|
55
|
+
idxfile = File.open(index_file, 'rb')
|
54
56
|
end
|
55
57
|
|
56
58
|
# read header
|
@@ -66,14 +68,14 @@ module Grit
|
|
66
68
|
@version = 1
|
67
69
|
end
|
68
70
|
|
69
|
-
idx =
|
71
|
+
idx = FileWindow.new(idxfile, @version)
|
70
72
|
yield idx
|
71
73
|
idx.unmap
|
72
74
|
idxfile.close
|
73
75
|
end
|
74
76
|
|
75
77
|
def with_packfile
|
76
|
-
packfile = File.open(@name)
|
78
|
+
packfile = File.open(@name, 'rb')
|
77
79
|
yield packfile
|
78
80
|
packfile.close
|
79
81
|
end
|
@@ -189,7 +191,7 @@ module Grit
|
|
189
191
|
end
|
190
192
|
|
191
193
|
def find_object_in_index(idx, sha1)
|
192
|
-
slot = sha1
|
194
|
+
slot = sha1.getord(0)
|
193
195
|
return nil if !slot
|
194
196
|
first, last = @offsets[slot,2]
|
195
197
|
while first < last
|
@@ -248,13 +250,13 @@ module Grit
|
|
248
250
|
obj_offset = offset
|
249
251
|
packfile.seek(offset)
|
250
252
|
|
251
|
-
c = packfile.read(1)
|
253
|
+
c = packfile.read(1).getord(0)
|
252
254
|
size = c & 0xf
|
253
255
|
type = (c >> 4) & 7
|
254
256
|
shift = 4
|
255
257
|
offset += 1
|
256
258
|
while c & 0x80 != 0
|
257
|
-
c = packfile.read(1)
|
259
|
+
c = packfile.read(1).getord(0)
|
258
260
|
size |= ((c & 0x7f) << shift)
|
259
261
|
shift += 7
|
260
262
|
offset += 1
|
@@ -265,7 +267,7 @@ module Grit
|
|
265
267
|
case type
|
266
268
|
when OBJ_OFS_DELTA, OBJ_REF_DELTA
|
267
269
|
data, type = unpack_deltified(packfile, type, offset, obj_offset, size, options)
|
268
|
-
#puts type
|
270
|
+
#puts "Type: #{type}"
|
269
271
|
when OBJ_COMMIT, OBJ_TREE, OBJ_BLOB, OBJ_TAG
|
270
272
|
data = unpack_compressed(offset, size)
|
271
273
|
else
|
@@ -281,10 +283,10 @@ module Grit
|
|
281
283
|
|
282
284
|
if type == OBJ_OFS_DELTA
|
283
285
|
i = 0
|
284
|
-
c = data
|
286
|
+
c = data.getord(i)
|
285
287
|
base_offset = c & 0x7f
|
286
288
|
while c & 0x80 != 0
|
287
|
-
c = data
|
289
|
+
c = data.getord(i += 1)
|
288
290
|
base_offset += 1
|
289
291
|
base_offset <<= 7
|
290
292
|
base_offset |= c & 0x7f
|
@@ -335,18 +337,18 @@ module Grit
|
|
335
337
|
dest_size, pos = patch_delta_header_size(delta, pos)
|
336
338
|
dest = ""
|
337
339
|
while pos < delta.size
|
338
|
-
c = delta
|
340
|
+
c = delta.getord(pos)
|
339
341
|
pos += 1
|
340
342
|
if c & 0x80 != 0
|
341
343
|
pos -= 1
|
342
344
|
cp_off = cp_size = 0
|
343
|
-
cp_off = delta
|
344
|
-
cp_off |= delta
|
345
|
-
cp_off |= delta
|
346
|
-
cp_off |= delta
|
347
|
-
cp_size = delta
|
348
|
-
cp_size |= delta
|
349
|
-
cp_size |= delta
|
345
|
+
cp_off = delta.getord(pos += 1) if c & 0x01 != 0
|
346
|
+
cp_off |= delta.getord(pos += 1) << 8 if c & 0x02 != 0
|
347
|
+
cp_off |= delta.getord(pos += 1) << 16 if c & 0x04 != 0
|
348
|
+
cp_off |= delta.getord(pos += 1) << 24 if c & 0x08 != 0
|
349
|
+
cp_size = delta.getord(pos += 1) if c & 0x10 != 0
|
350
|
+
cp_size |= delta.getord(pos += 1) << 8 if c & 0x20 != 0
|
351
|
+
cp_size |= delta.getord(pos += 1) << 16 if c & 0x40 != 0
|
350
352
|
cp_size = 0x10000 if cp_size == 0
|
351
353
|
pos += 1
|
352
354
|
dest += base[cp_off,cp_size]
|
@@ -365,7 +367,7 @@ module Grit
|
|
365
367
|
size = 0
|
366
368
|
shift = 0
|
367
369
|
begin
|
368
|
-
c = delta
|
370
|
+
c = delta.getord(pos)
|
369
371
|
if c == nil
|
370
372
|
raise PackFormatError, 'invalid delta header'
|
371
373
|
end
|
data/lib/grit/git-ruby/object.rb
CHANGED
@@ -163,8 +163,14 @@ module Grit
|
|
163
163
|
|
164
164
|
def self.read_bytes_until(io, char)
|
165
165
|
string = ''
|
166
|
-
|
167
|
-
|
166
|
+
if RUBY_VERSION > '1.9'
|
167
|
+
while ((next_char = io.getc) != char) && !io.eof
|
168
|
+
string += next_char
|
169
|
+
end
|
170
|
+
else
|
171
|
+
while ((next_char = io.getc.chr) != char) && !io.eof
|
172
|
+
string += next_char
|
173
|
+
end
|
168
174
|
end
|
169
175
|
string
|
170
176
|
end
|
@@ -37,7 +37,7 @@ module Grit
|
|
37
37
|
def initialize(git_dir, options = {})
|
38
38
|
@git_dir = git_dir
|
39
39
|
@options = options
|
40
|
-
|
40
|
+
#@packs = []
|
41
41
|
end
|
42
42
|
|
43
43
|
# returns the loose objects object lazily
|
@@ -92,7 +92,7 @@ module Grit
|
|
92
92
|
return o if o
|
93
93
|
end
|
94
94
|
|
95
|
-
|
95
|
+
puts "*#{sha1o}*"
|
96
96
|
raise NoSuchShaFound
|
97
97
|
end
|
98
98
|
|
@@ -185,16 +185,15 @@ module Grit
|
|
185
185
|
def get_raw_tree(sha)
|
186
186
|
o = get_raw_object_by_sha1(sha)
|
187
187
|
if o.type == :commit
|
188
|
-
|
188
|
+
cat_file(get_object_by_sha1(sha).tree)
|
189
189
|
elsif o.type == :tag
|
190
190
|
commit_sha = get_object_by_sha1(sha).object
|
191
|
-
|
192
|
-
|
193
|
-
|
191
|
+
cat_file(get_object_by_sha1(commit_sha).tree)
|
192
|
+
elsif o.type == :tree
|
193
|
+
cat_file(sha)
|
194
194
|
end
|
195
|
-
return tree
|
196
195
|
end
|
197
|
-
|
196
|
+
|
198
197
|
# return array of tree entries
|
199
198
|
## TODO : refactor this to remove the fugly
|
200
199
|
def ls_tree_path(sha, path, append = nil)
|
@@ -376,37 +375,41 @@ module Grit
|
|
376
375
|
else
|
377
376
|
tree2 = get_object_by_sha1(commit_obj1.parent.first).tree
|
378
377
|
end
|
379
|
-
|
378
|
+
|
380
379
|
qdiff = quick_diff(tree1, tree2)
|
381
|
-
|
380
|
+
|
382
381
|
qdiff.sort.each do |diff_arr|
|
382
|
+
path, status, treeSHA1, treeSHA2 = *diff_arr
|
383
383
|
format, lines, output = :unified, 3, ''
|
384
384
|
file_length_difference = 0
|
385
|
-
|
386
|
-
fileA =
|
387
|
-
fileB =
|
388
|
-
|
389
|
-
sha1 =
|
390
|
-
sha2 =
|
385
|
+
|
386
|
+
fileA = treeSHA1 ? cat_file(treeSHA1) : ''
|
387
|
+
fileB = treeSHA2 ? cat_file(treeSHA2) : ''
|
388
|
+
|
389
|
+
sha1 = treeSHA1 || '0000000000000000000000000000000000000000'
|
390
|
+
sha2 = treeSHA2 || '0000000000000000000000000000000000000000'
|
391
391
|
|
392
392
|
data_old = fileA.split(/\n/).map! { |e| e.chomp }
|
393
393
|
data_new = fileB.split(/\n/).map! { |e| e.chomp }
|
394
|
-
|
395
|
-
diffs = Difference::LCS.diff(data_old, data_new)
|
394
|
+
|
395
|
+
diffs = Difference::LCS.diff(data_old, data_new)
|
396
396
|
next if diffs.empty?
|
397
397
|
|
398
|
-
|
398
|
+
a_path = "a/#{path.gsub('./', '')}"
|
399
|
+
b_path = "b/#{path.gsub('./', '')}"
|
400
|
+
|
401
|
+
header = "diff --git #{a_path} #{b_path}"
|
399
402
|
if options[:full_index]
|
400
403
|
header << "\n" + 'index ' + sha1 + '..' + sha2
|
401
|
-
header << ' 100644' if
|
404
|
+
header << ' 100644' if treeSHA2 # hard coding this because i don't think we use it
|
402
405
|
else
|
403
406
|
header << "\n" + 'index ' + sha1[0,7] + '..' + sha2[0,7]
|
404
|
-
header << ' 100644' if
|
407
|
+
header << ' 100644' if treeSHA2 # hard coding this because i don't think we use it
|
405
408
|
end
|
406
|
-
header << "\n--- " +
|
407
|
-
header << "\n+++ " +
|
409
|
+
header << "\n--- " + (treeSHA1 ? a_path : '/dev/null')
|
410
|
+
header << "\n+++ " + (treeSHA2 ? b_path : '/dev/null')
|
408
411
|
header += "\n"
|
409
|
-
|
412
|
+
|
410
413
|
oldhunk = hunk = nil
|
411
414
|
|
412
415
|
diffs.each do |piece|
|
@@ -664,6 +667,7 @@ module Grit
|
|
664
667
|
private
|
665
668
|
|
666
669
|
def initloose
|
670
|
+
@loaded = []
|
667
671
|
@loose = []
|
668
672
|
load_loose(git_path('objects'))
|
669
673
|
load_alternate_loose(git_path('objects'))
|
@@ -675,6 +679,7 @@ module Grit
|
|
675
679
|
alt = File.join(path, 'info/alternates')
|
676
680
|
if File.exists?(alt)
|
677
681
|
File.readlines(alt).each do |line|
|
682
|
+
next if @loaded.include?(line.chomp)
|
678
683
|
if line[0, 2] == '..'
|
679
684
|
line = File.expand_path(File.join(@git_dir, line))
|
680
685
|
end
|
@@ -685,12 +690,14 @@ module Grit
|
|
685
690
|
end
|
686
691
|
|
687
692
|
def load_loose(path)
|
693
|
+
@loaded << path
|
688
694
|
return if !File.exists?(path)
|
689
695
|
@loose << Grit::GitRuby::Internal::LooseStorage.new(path)
|
690
696
|
end
|
691
697
|
|
692
698
|
def initpacks
|
693
699
|
close
|
700
|
+
@loaded_packs = []
|
694
701
|
@packs = []
|
695
702
|
load_packs(git_path("objects/pack"))
|
696
703
|
load_alternate_packs(git_path('objects'))
|
@@ -705,6 +712,7 @@ module Grit
|
|
705
712
|
line = File.expand_path(File.join(@git_dir, line))
|
706
713
|
end
|
707
714
|
full_pack = File.join(line.chomp, 'pack')
|
715
|
+
next if @loaded_packs.include?(full_pack)
|
708
716
|
load_packs(full_pack)
|
709
717
|
load_alternate_packs(File.join(line.chomp))
|
710
718
|
end
|
@@ -712,6 +720,7 @@ module Grit
|
|
712
720
|
end
|
713
721
|
|
714
722
|
def load_packs(path)
|
723
|
+
@loaded_packs << path
|
715
724
|
return if !File.exists?(path)
|
716
725
|
Dir.open(path) do |dir|
|
717
726
|
dir.each do |entry|
|
data/lib/grit/git.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'tempfile'
|
1
2
|
module Grit
|
2
3
|
|
3
4
|
class Git
|
@@ -13,13 +14,33 @@ module Grit
|
|
13
14
|
undef_method :clone
|
14
15
|
|
15
16
|
include GitRuby
|
16
|
-
|
17
|
+
|
18
|
+
def exist?
|
19
|
+
File.exist?(self.git_dir)
|
20
|
+
end
|
21
|
+
|
22
|
+
def put_raw_object(content, type)
|
23
|
+
ruby_git.put_raw_object(content, type)
|
24
|
+
end
|
25
|
+
|
26
|
+
def object_exists?(object_id)
|
27
|
+
ruby_git.object_exists?(object_id)
|
28
|
+
end
|
29
|
+
|
17
30
|
class << self
|
18
|
-
attr_accessor :git_binary, :git_timeout
|
31
|
+
attr_accessor :git_binary, :git_timeout, :git_max_size
|
19
32
|
end
|
20
33
|
|
21
|
-
self.git_binary
|
22
|
-
self.git_timeout
|
34
|
+
self.git_binary = "/usr/bin/env git"
|
35
|
+
self.git_timeout = 10
|
36
|
+
self.git_max_size = 5242880 # 5.megabytes
|
37
|
+
|
38
|
+
def self.with_timeout(timeout = 10.seconds)
|
39
|
+
old_timeout = Grit::Git.git_timeout
|
40
|
+
Grit::Git.git_timeout = timeout
|
41
|
+
yield
|
42
|
+
Grit::Git.git_timeout = old_timeout
|
43
|
+
end
|
23
44
|
|
24
45
|
attr_accessor :git_dir, :bytes_read
|
25
46
|
|
@@ -28,6 +49,152 @@ module Grit
|
|
28
49
|
self.bytes_read = 0
|
29
50
|
end
|
30
51
|
|
52
|
+
def shell_escape(str)
|
53
|
+
str.to_s.gsub("'", "\\\\'").gsub(";", '\\;')
|
54
|
+
end
|
55
|
+
alias_method :e, :shell_escape
|
56
|
+
|
57
|
+
# Check if a normal file exists on the filesystem
|
58
|
+
# +file+ is the relative path from the Git dir
|
59
|
+
#
|
60
|
+
# Returns Boolean
|
61
|
+
def fs_exist?(file)
|
62
|
+
File.exist?(File.join(self.git_dir, file))
|
63
|
+
end
|
64
|
+
|
65
|
+
# Read a normal file from the filesystem.
|
66
|
+
# +file+ is the relative path from the Git dir
|
67
|
+
#
|
68
|
+
# Returns the String contents of the file
|
69
|
+
def fs_read(file)
|
70
|
+
File.open(File.join(self.git_dir, file)).read
|
71
|
+
end
|
72
|
+
|
73
|
+
# Write a normal file to the filesystem.
|
74
|
+
# +file+ is the relative path from the Git dir
|
75
|
+
# +contents+ is the String content to be written
|
76
|
+
#
|
77
|
+
# Returns nothing
|
78
|
+
def fs_write(file, contents)
|
79
|
+
path = File.join(self.git_dir, file)
|
80
|
+
FileUtils.mkdir_p(File.dirname(path))
|
81
|
+
File.open(path, 'w') do |f|
|
82
|
+
f.write(contents)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Delete a normal file from the filesystem
|
87
|
+
# +file+ is the relative path from the Git dir
|
88
|
+
#
|
89
|
+
# Returns nothing
|
90
|
+
def fs_delete(file)
|
91
|
+
FileUtils.rm_rf(File.join(self.git_dir, file))
|
92
|
+
end
|
93
|
+
|
94
|
+
# Move a normal file
|
95
|
+
# +from+ is the relative path to the current file
|
96
|
+
# +to+ is the relative path to the destination file
|
97
|
+
#
|
98
|
+
# Returns nothing
|
99
|
+
def fs_move(from, to)
|
100
|
+
FileUtils.mv(File.join(self.git_dir, from), File.join(self.git_dir, to))
|
101
|
+
end
|
102
|
+
|
103
|
+
# Make a directory
|
104
|
+
# +dir+ is the relative path to the directory to create
|
105
|
+
#
|
106
|
+
# Returns nothing
|
107
|
+
def fs_mkdir(dir)
|
108
|
+
FileUtils.mkdir_p(File.join(self.git_dir, dir))
|
109
|
+
end
|
110
|
+
|
111
|
+
# Chmod the the file or dir and everything beneath
|
112
|
+
# +file+ is the relative path from the Git dir
|
113
|
+
#
|
114
|
+
# Returns nothing
|
115
|
+
def fs_chmod(mode, file = '/')
|
116
|
+
FileUtils.chmod_R(mode, File.join(self.git_dir, file))
|
117
|
+
end
|
118
|
+
|
119
|
+
# Create a new directory
|
120
|
+
# +path+ is an absolute path
|
121
|
+
#
|
122
|
+
# Returns nothing
|
123
|
+
def fs_mkdir(path)
|
124
|
+
FileUtils.mkdir_p(path)
|
125
|
+
end
|
126
|
+
|
127
|
+
def fs_exist(path)
|
128
|
+
File.exist?(path)
|
129
|
+
end
|
130
|
+
|
131
|
+
def list_remotes
|
132
|
+
remotes = []
|
133
|
+
Dir.chdir(File.join(self.git_dir, 'refs/remotes')) do
|
134
|
+
remotes = Dir.glob('*')
|
135
|
+
end
|
136
|
+
remotes
|
137
|
+
rescue
|
138
|
+
[]
|
139
|
+
end
|
140
|
+
|
141
|
+
def create_tempfile(seed, unlink = false)
|
142
|
+
path = Tempfile.new(seed).path
|
143
|
+
File.unlink(path) if unlink
|
144
|
+
return path
|
145
|
+
end
|
146
|
+
|
147
|
+
def check_applies(head_sha, applies_sha)
|
148
|
+
git_index = create_tempfile('index', true)
|
149
|
+
(o1, exit1) = raw_git("git read-tree #{head_sha} 2>/dev/null", git_index)
|
150
|
+
(o2, exit2) = raw_git("git diff #{applies_sha}^ #{applies_sha} | git apply --check --cached >/dev/null 2>/dev/null", git_index)
|
151
|
+
return (exit1 + exit2)
|
152
|
+
end
|
153
|
+
|
154
|
+
def get_patch(applies_sha)
|
155
|
+
git_index = create_tempfile('index', true)
|
156
|
+
(patch, exit2) = raw_git("git diff #{applies_sha}^ #{applies_sha}", git_index)
|
157
|
+
patch
|
158
|
+
end
|
159
|
+
|
160
|
+
def apply_patch(head_sha, patch)
|
161
|
+
git_index = create_tempfile('index', true)
|
162
|
+
|
163
|
+
git_patch = create_tempfile('patch')
|
164
|
+
File.open(git_patch, 'w+') { |f| f.print patch }
|
165
|
+
|
166
|
+
raw_git("git read-tree #{head_sha} 2>/dev/null", git_index)
|
167
|
+
(op, exit) = raw_git("git apply --cached < #{git_patch}", git_index)
|
168
|
+
if exit == 0
|
169
|
+
return raw_git("git write-tree", git_index).first.chomp
|
170
|
+
end
|
171
|
+
false
|
172
|
+
end
|
173
|
+
|
174
|
+
# RAW CALLS WITH ENV SETTINGS
|
175
|
+
def raw_git_call(command, index)
|
176
|
+
tmp = ENV['GIT_INDEX_FILE']
|
177
|
+
ENV['GIT_INDEX_FILE'] = index
|
178
|
+
out = `#{command}`
|
179
|
+
after = ENV['GIT_INDEX_FILE'] # someone fucking with us ??
|
180
|
+
ENV['GIT_INDEX_FILE'] = tmp
|
181
|
+
if after != index
|
182
|
+
raise 'environment was changed for the git call'
|
183
|
+
end
|
184
|
+
[out, $?.exitstatus]
|
185
|
+
end
|
186
|
+
|
187
|
+
def raw_git(command, index)
|
188
|
+
output = nil
|
189
|
+
Dir.chdir(self.git_dir) do
|
190
|
+
output = raw_git_call(command, index)
|
191
|
+
end
|
192
|
+
output
|
193
|
+
end
|
194
|
+
# RAW CALLS WITH ENV SETTINGS END
|
195
|
+
|
196
|
+
|
197
|
+
|
31
198
|
# Run the given git command with the specified arguments and return
|
32
199
|
# the result as a String
|
33
200
|
# +cmd+ is the command
|
@@ -42,14 +209,21 @@ module Grit
|
|
42
209
|
run('', cmd, '', options, args)
|
43
210
|
end
|
44
211
|
|
212
|
+
# Bypass any pure Ruby implementations and go straight to the native Git command
|
213
|
+
#
|
214
|
+
# Returns String
|
215
|
+
def native(cmd, options = {}, *args)
|
216
|
+
method_missing(cmd, options, *args)
|
217
|
+
end
|
218
|
+
|
45
219
|
def run(prefix, cmd, postfix, options, args)
|
46
|
-
timeout = options.delete(:timeout)
|
220
|
+
timeout = options.delete(:timeout) rescue nil
|
47
221
|
timeout = true if timeout.nil?
|
48
222
|
|
49
223
|
opt_args = transform_options(options)
|
50
|
-
ext_args = args.reject { |a| a.empty? }.map { |a| (a == '--' || a[0].chr == '|') ? a : "'#{a}'" }
|
51
|
-
|
52
|
-
call = "#{prefix}#{Git.git_binary} --git-dir='#{self.git_dir}' #{cmd.to_s.gsub(/_/, '-')} #{(opt_args + ext_args).join(' ')}#{postfix}"
|
224
|
+
ext_args = args.reject { |a| a.empty? }.map { |a| (a == '--' || a[0].chr == '|' || Grit.no_quote) ? a : "'#{e(a)}'" }
|
225
|
+
|
226
|
+
call = "#{prefix}#{Git.git_binary} --git-dir='#{self.git_dir}' #{cmd.to_s.gsub(/_/, '-')} #{(opt_args + ext_args).join(' ')}#{e(postfix)}"
|
53
227
|
Grit.log(call) if Grit.debug
|
54
228
|
response, err = timeout ? sh(call) : wild_sh(call)
|
55
229
|
Grit.log(response) if Grit.debug
|
@@ -63,7 +237,7 @@ module Grit
|
|
63
237
|
Timeout.timeout(self.class.git_timeout) do
|
64
238
|
while tmp = stdout.read(1024)
|
65
239
|
ret += tmp
|
66
|
-
if (@bytes_read += tmp.size) >
|
240
|
+
if (@bytes_read += tmp.size) > self.class.git_max_size
|
67
241
|
bytes = @bytes_read
|
68
242
|
@bytes_read = 0
|
69
243
|
raise GitTimeout.new(command, bytes)
|
@@ -107,16 +281,20 @@ module Grit
|
|
107
281
|
if opt.to_s.size == 1
|
108
282
|
if options[opt] == true
|
109
283
|
args << "-#{opt}"
|
284
|
+
elsif options[opt] == false
|
285
|
+
# ignore
|
110
286
|
else
|
111
287
|
val = options.delete(opt)
|
112
|
-
args << "-#{opt.to_s} '#{val}'"
|
288
|
+
args << "-#{opt.to_s} '#{e(val)}'"
|
113
289
|
end
|
114
290
|
else
|
115
291
|
if options[opt] == true
|
116
292
|
args << "--#{opt.to_s.gsub(/_/, '-')}"
|
293
|
+
elsif options[opt] == false
|
294
|
+
# ignore
|
117
295
|
else
|
118
296
|
val = options.delete(opt)
|
119
|
-
args << "--#{opt.to_s.gsub(/_/, '-')}='#{val}'"
|
297
|
+
args << "--#{opt.to_s.gsub(/_/, '-')}='#{e(val)}'"
|
120
298
|
end
|
121
299
|
end
|
122
300
|
end
|