git 1.0.4 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of git might be problematic. Click here for more details.
- data/README +4 -13
- data/lib/git.rb +6 -2
- data/lib/git/base.rb +37 -5
- data/lib/git/branch.rb +5 -0
- data/lib/git/branches.rb +12 -0
- data/lib/git/lib.rb +157 -25
- data/lib/git/lib.rb.orig +620 -0
- data/lib/git/object.rb +13 -5
- data/lib/git/stash.rb +26 -0
- data/lib/git/stashes.rb +49 -0
- data/tests/files/working.git/info/refs +10 -0
- data/tests/files/working.git/objects/info/packs +2 -0
- data/tests/files/working.git/objects/pack/pack-6e99d3a243c58205968336728d5637ce2a3b2aff.idx +0 -0
- data/tests/files/working.git/objects/pack/pack-6e99d3a243c58205968336728d5637ce2a3b2aff.pack +0 -0
- data/tests/files/working/dot_git/config +3 -0
- data/tests/test_helper.rb +11 -0
- data/tests/units/test_config.rb +3 -3
- data/tests/units/test_each_conflict.rb +49 -0
- data/tests/units/test_index_ops.rb +1 -1
- data/tests/units/test_lib.rb +9 -0
- data/tests/units/test_log.rb +2 -1
- data/tests/units/test_logger.rb +38 -0
- data/tests/units/test_object.rb +5 -0
- data/tests/units/test_stashes.rb +36 -0
- metadata +12 -2
data/lib/git/lib.rb.orig
ADDED
@@ -0,0 +1,620 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
module Git
|
4
|
+
|
5
|
+
class GitExecuteError < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
class Lib
|
9
|
+
|
10
|
+
@git_dir = nil
|
11
|
+
@git_index_file = nil
|
12
|
+
@git_work_dir = nil
|
13
|
+
@path = nil
|
14
|
+
|
15
|
+
@logger = nil
|
16
|
+
|
17
|
+
def initialize(base = nil, logger = nil)
|
18
|
+
if base.is_a?(Git::Base)
|
19
|
+
@git_dir = base.repo.path
|
20
|
+
@git_index_file = base.index.path if base.index
|
21
|
+
@git_work_dir = base.dir.path if base.dir
|
22
|
+
elsif base.is_a?(Hash)
|
23
|
+
@git_dir = base[:repository]
|
24
|
+
@git_index_file = base[:index]
|
25
|
+
@git_work_dir = base[:working_directory]
|
26
|
+
end
|
27
|
+
if logger
|
28
|
+
@logger = logger
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def init
|
33
|
+
command('init')
|
34
|
+
end
|
35
|
+
|
36
|
+
# tries to clone the given repo
|
37
|
+
#
|
38
|
+
# returns {:repository} (if bare)
|
39
|
+
# {:working_directory} otherwise
|
40
|
+
#
|
41
|
+
# accepts options:
|
42
|
+
# :remote - name of remote (rather than 'origin')
|
43
|
+
# :bare - no working directory
|
44
|
+
#
|
45
|
+
# TODO - make this work with SSH password or auth_key
|
46
|
+
#
|
47
|
+
def clone(repository, name, opts = {})
|
48
|
+
@path = opts[:path] || '.'
|
49
|
+
opts[:path] ? clone_dir = File.join(@path, name) : clone_dir = name
|
50
|
+
|
51
|
+
arr_opts = []
|
52
|
+
arr_opts << "--bare" if opts[:bare]
|
53
|
+
arr_opts << "-o #{opts[:remote]}" if opts[:remote]
|
54
|
+
arr_opts << repository
|
55
|
+
arr_opts << clone_dir
|
56
|
+
|
57
|
+
command('clone', arr_opts)
|
58
|
+
|
59
|
+
opts[:bare] ? {:repository => clone_dir} : {:working_directory => clone_dir}
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
## READ COMMANDS ##
|
64
|
+
|
65
|
+
|
66
|
+
def log_commits(opts = {})
|
67
|
+
arr_opts = ['--pretty=oneline']
|
68
|
+
arr_opts << "-#{opts[:count]}" if opts[:count]
|
69
|
+
arr_opts << "--since=\"#{opts[:since]}\"" if opts[:since].is_a? String
|
70
|
+
arr_opts << "#{opts[:between][0].to_s}..#{opts[:between][1].to_s}" if (opts[:between] && opts[:between].size == 2)
|
71
|
+
arr_opts << opts[:object] if opts[:object].is_a? String
|
72
|
+
arr_opts << '-- ' + opts[:path_limiter] if opts[:path_limiter].is_a? String
|
73
|
+
|
74
|
+
command_lines('log', arr_opts, true).map { |l| l.split.first }
|
75
|
+
end
|
76
|
+
|
77
|
+
def full_log_commits(opts = {})
|
78
|
+
arr_opts = ['--pretty=raw']
|
79
|
+
arr_opts << "-#{opts[:count]}" if opts[:count]
|
80
|
+
arr_opts << "--since=\"#{opts[:since]}\"" if opts[:since].is_a? String
|
81
|
+
arr_opts << "#{opts[:between][0].to_s}..#{opts[:between][1].to_s}" if (opts[:between] && opts[:between].size == 2)
|
82
|
+
arr_opts << opts[:object] if opts[:object].is_a? String
|
83
|
+
arr_opts << '-- ' + opts[:path_limiter] if opts[:path_limiter].is_a? String
|
84
|
+
|
85
|
+
full_log = command_lines('log', arr_opts, true)
|
86
|
+
process_commit_data(full_log)
|
87
|
+
end
|
88
|
+
|
89
|
+
def revparse(string)
|
90
|
+
if /\w{40}/.match(string) # passing in a sha - just no-op it
|
91
|
+
return string
|
92
|
+
end
|
93
|
+
|
94
|
+
head = File.join(@git_dir, 'refs', 'heads', string)
|
95
|
+
return File.read(head).chomp if File.file?(head)
|
96
|
+
|
97
|
+
head = File.join(@git_dir, 'refs', 'remotes', string)
|
98
|
+
return File.read(head).chomp if File.file?(head)
|
99
|
+
|
100
|
+
head = File.join(@git_dir, 'refs', 'tags', string)
|
101
|
+
return File.read(head).chomp if File.file?(head)
|
102
|
+
|
103
|
+
command('rev-parse', string)
|
104
|
+
end
|
105
|
+
|
106
|
+
def namerev(string)
|
107
|
+
command('name-rev', string).split[1]
|
108
|
+
end
|
109
|
+
|
110
|
+
def object_type(sha)
|
111
|
+
command('cat-file', ['-t', sha])
|
112
|
+
end
|
113
|
+
|
114
|
+
def object_size(sha)
|
115
|
+
command('cat-file', ['-s', sha]).to_i
|
116
|
+
end
|
117
|
+
|
118
|
+
# returns useful array of raw commit object data
|
119
|
+
def commit_data(sha)
|
120
|
+
sha = sha.to_s
|
121
|
+
cdata = command_lines('cat-file', ['commit', sha])
|
122
|
+
process_commit_data(cdata, sha)
|
123
|
+
end
|
124
|
+
|
125
|
+
def process_commit_data(data, sha = nil)
|
126
|
+
in_message = false
|
127
|
+
|
128
|
+
if sha
|
129
|
+
hsh = {'sha' => sha, 'message' => '', 'parent' => []}
|
130
|
+
else
|
131
|
+
hsh_array = []
|
132
|
+
end
|
133
|
+
|
134
|
+
data.each do |line|
|
135
|
+
line = line.chomp
|
136
|
+
if in_message && line != ''
|
137
|
+
hsh['message'] += line + "\n"
|
138
|
+
end
|
139
|
+
|
140
|
+
if (line != '') && !in_message
|
141
|
+
data = line.split
|
142
|
+
key = data.shift
|
143
|
+
value = data.join(' ')
|
144
|
+
if key == 'commit'
|
145
|
+
sha = value
|
146
|
+
hsh_array << hsh if hsh
|
147
|
+
hsh = {'sha' => sha, 'message' => '', 'parent' => []}
|
148
|
+
end
|
149
|
+
if key == 'parent'
|
150
|
+
hsh[key] << value
|
151
|
+
else
|
152
|
+
hsh[key] = value
|
153
|
+
end
|
154
|
+
elsif in_message && line == ''
|
155
|
+
in_message = false
|
156
|
+
else
|
157
|
+
in_message = true
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
if hsh_array
|
162
|
+
hsh_array << hsh if hsh
|
163
|
+
hsh_array
|
164
|
+
else
|
165
|
+
hsh
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def object_contents(sha)
|
170
|
+
command('cat-file', ['-p', sha])
|
171
|
+
end
|
172
|
+
|
173
|
+
def ls_tree(sha)
|
174
|
+
data = {'blob' => {}, 'tree' => {}}
|
175
|
+
|
176
|
+
command_lines('ls-tree', sha.to_s).each do |line|
|
177
|
+
(info, filenm) = line.split("\t")
|
178
|
+
(mode, type, sha) = info.split
|
179
|
+
data[type][filenm] = {:mode => mode, :sha => sha}
|
180
|
+
end
|
181
|
+
|
182
|
+
data
|
183
|
+
end
|
184
|
+
|
185
|
+
def full_tree(sha)
|
186
|
+
command_lines('ls-tree', ['-r', sha.to_s])
|
187
|
+
end
|
188
|
+
|
189
|
+
def tree_depth(sha)
|
190
|
+
full_tree(sha).size
|
191
|
+
end
|
192
|
+
|
193
|
+
def branches_all
|
194
|
+
head = File.read(File.join(@git_dir, 'HEAD'))
|
195
|
+
arr = []
|
196
|
+
|
197
|
+
if m = /ref: refs\/heads\/(.*)/.match(head)
|
198
|
+
current = m[1]
|
199
|
+
end
|
200
|
+
arr += list_files('heads').map { |f| [f, f == current] }
|
201
|
+
arr += list_files('remotes').map { |f| [f, false] }
|
202
|
+
|
203
|
+
#command_lines('branch', '-a').each do |b|
|
204
|
+
# current = false
|
205
|
+
# current = true if b[0, 2] == '* '
|
206
|
+
# arr << [b.gsub('* ', '').strip, current]
|
207
|
+
#end
|
208
|
+
|
209
|
+
arr
|
210
|
+
end
|
211
|
+
|
212
|
+
def list_files(ref_dir)
|
213
|
+
dir = File.join(@git_dir, 'refs', ref_dir)
|
214
|
+
files = nil
|
215
|
+
Dir.chdir(dir) { files = Dir.glob('**/*').select { |f| File.file?(f) } }
|
216
|
+
files
|
217
|
+
end
|
218
|
+
|
219
|
+
def branch_current
|
220
|
+
branches_all.select { |b| b[1] }.first[0] rescue nil
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
# returns hash
|
225
|
+
# [tree-ish] = [[line_no, match], [line_no, match2]]
|
226
|
+
# [tree-ish] = [[line_no, match], [line_no, match2]]
|
227
|
+
def grep(string, opts = {})
|
228
|
+
opts[:object] = 'HEAD' if !opts[:object]
|
229
|
+
|
230
|
+
grep_opts = ['-n']
|
231
|
+
grep_opts << '-i' if opts[:ignore_case]
|
232
|
+
grep_opts << '-v' if opts[:invert_match]
|
233
|
+
grep_opts << "-e '#{string}'"
|
234
|
+
grep_opts << opts[:object] if opts[:object].is_a?(String)
|
235
|
+
grep_opts << ('-- ' + opts[:path_limiter]) if opts[:path_limiter].is_a? String
|
236
|
+
hsh = {}
|
237
|
+
command_lines('grep', grep_opts).each do |line|
|
238
|
+
if m = /(.*)\:(\d+)\:(.*)/.match(line)
|
239
|
+
hsh[m[1]] ||= []
|
240
|
+
hsh[m[1]] << [m[2].to_i, m[3]]
|
241
|
+
end
|
242
|
+
end
|
243
|
+
hsh
|
244
|
+
end
|
245
|
+
|
246
|
+
def diff_full(obj1 = 'HEAD', obj2 = nil, opts = {})
|
247
|
+
diff_opts = ['-p']
|
248
|
+
diff_opts << obj1
|
249
|
+
diff_opts << obj2 if obj2.is_a?(String)
|
250
|
+
diff_opts << ('-- ' + opts[:path_limiter]) if opts[:path_limiter].is_a? String
|
251
|
+
|
252
|
+
command('diff', diff_opts)
|
253
|
+
end
|
254
|
+
|
255
|
+
def diff_stats(obj1 = 'HEAD', obj2 = nil, opts = {})
|
256
|
+
diff_opts = ['--numstat']
|
257
|
+
diff_opts << obj1
|
258
|
+
diff_opts << obj2 if obj2.is_a?(String)
|
259
|
+
diff_opts << ('-- ' + opts[:path_limiter]) if opts[:path_limiter].is_a? String
|
260
|
+
|
261
|
+
hsh = {:total => {:insertions => 0, :deletions => 0, :lines => 0, :files => 0}, :files => {}}
|
262
|
+
|
263
|
+
command_lines('diff', diff_opts).each do |file|
|
264
|
+
(insertions, deletions, filename) = file.split("\t")
|
265
|
+
hsh[:total][:insertions] += insertions.to_i
|
266
|
+
hsh[:total][:deletions] += deletions.to_i
|
267
|
+
hsh[:total][:lines] = (hsh[:total][:deletions] + hsh[:total][:insertions])
|
268
|
+
hsh[:total][:files] += 1
|
269
|
+
hsh[:files][filename] = {:insertions => insertions.to_i, :deletions => deletions.to_i}
|
270
|
+
end
|
271
|
+
|
272
|
+
hsh
|
273
|
+
end
|
274
|
+
|
275
|
+
# compares the index and the working directory
|
276
|
+
def diff_files
|
277
|
+
hsh = {}
|
278
|
+
command_lines('diff-files').each do |line|
|
279
|
+
(info, file) = line.split("\t")
|
280
|
+
(mode_src, mode_dest, sha_src, sha_dest, type) = info.split
|
281
|
+
hsh[file] = {:path => file, :mode_file => mode_src.to_s[1, 7], :mode_index => mode_dest,
|
282
|
+
:sha_file => sha_src, :sha_index => sha_dest, :type => type}
|
283
|
+
end
|
284
|
+
hsh
|
285
|
+
end
|
286
|
+
|
287
|
+
# compares the index and the repository
|
288
|
+
def diff_index(treeish)
|
289
|
+
hsh = {}
|
290
|
+
command_lines('diff-index', treeish).each do |line|
|
291
|
+
(info, file) = line.split("\t")
|
292
|
+
(mode_src, mode_dest, sha_src, sha_dest, type) = info.split
|
293
|
+
hsh[file] = {:path => file, :mode_repo => mode_src.to_s[1, 7], :mode_index => mode_dest,
|
294
|
+
:sha_repo => sha_src, :sha_index => sha_dest, :type => type}
|
295
|
+
end
|
296
|
+
hsh
|
297
|
+
end
|
298
|
+
|
299
|
+
def ls_files
|
300
|
+
hsh = {}
|
301
|
+
command_lines('ls-files', '--stage').each do |line|
|
302
|
+
(info, file) = line.split("\t")
|
303
|
+
(mode, sha, stage) = info.split
|
304
|
+
hsh[file] = {:path => file, :mode_index => mode, :sha_index => sha, :stage => stage}
|
305
|
+
end
|
306
|
+
hsh
|
307
|
+
end
|
308
|
+
|
309
|
+
|
310
|
+
def config_remote(name)
|
311
|
+
hsh = {}
|
312
|
+
config_list.each do |key, value|
|
313
|
+
if /remote.#{name}/.match(key)
|
314
|
+
hsh[key.gsub("remote.#{name}.", '')] = value
|
315
|
+
end
|
316
|
+
end
|
317
|
+
hsh
|
318
|
+
end
|
319
|
+
|
320
|
+
def config_get(name)
|
321
|
+
c = config_list
|
322
|
+
c[name]
|
323
|
+
#command('config', ['--get', name])
|
324
|
+
end
|
325
|
+
|
326
|
+
def config_list
|
327
|
+
config = {}
|
328
|
+
config.merge!(parse_config('~/.gitconfig'))
|
329
|
+
config.merge!(parse_config(File.join(@git_dir, 'config')))
|
330
|
+
#hsh = {}
|
331
|
+
#command_lines('config', ['--list']).each do |line|
|
332
|
+
# (key, value) = line.split('=')
|
333
|
+
# hsh[key] = value
|
334
|
+
#end
|
335
|
+
#hsh
|
336
|
+
end
|
337
|
+
|
338
|
+
def parse_config(file)
|
339
|
+
hsh = {}
|
340
|
+
file = File.expand_path(file)
|
341
|
+
if File.file?(file)
|
342
|
+
current_section = nil
|
343
|
+
File.readlines(file).each do |line|
|
344
|
+
if m = /\[(\w+)\]/.match(line)
|
345
|
+
current_section = m[1]
|
346
|
+
elsif m = /\[(\w+?) "(.*?)"\]/.match(line)
|
347
|
+
current_section = "#{m[1]}.#{m[2]}"
|
348
|
+
elsif m = /(\w+?) = (.*)/.match(line)
|
349
|
+
key = "#{current_section}.#{m[1]}"
|
350
|
+
hsh[key] = m[2]
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
hsh
|
355
|
+
end
|
356
|
+
|
357
|
+
## WRITE COMMANDS ##
|
358
|
+
|
359
|
+
def config_set(name, value)
|
360
|
+
command('config', [name, "'#{value}'"])
|
361
|
+
end
|
362
|
+
|
363
|
+
def add(path = '.')
|
364
|
+
path = path.join(' ') if path.is_a?(Array)
|
365
|
+
command('add', path)
|
366
|
+
end
|
367
|
+
|
368
|
+
def remove(path = '.', opts = {})
|
369
|
+
path = path.join(' ') if path.is_a?(Array)
|
370
|
+
|
371
|
+
arr_opts = ['-f'] # overrides the up-to-date check by default
|
372
|
+
arr_opts << ['-r'] if opts[:recursive]
|
373
|
+
arr_opts << path
|
374
|
+
|
375
|
+
command('rm', arr_opts)
|
376
|
+
end
|
377
|
+
|
378
|
+
def commit(message, opts = {})
|
379
|
+
arr_opts = ["-m '#{message}'"]
|
380
|
+
arr_opts << '-a' if opts[:add_all]
|
381
|
+
command('commit', arr_opts)
|
382
|
+
end
|
383
|
+
|
384
|
+
def reset(commit, opts = {})
|
385
|
+
arr_opts = []
|
386
|
+
arr_opts << '--hard' if opts[:hard]
|
387
|
+
arr_opts << commit.to_s if commit
|
388
|
+
command('reset', arr_opts)
|
389
|
+
end
|
390
|
+
|
391
|
+
def stashes_all
|
392
|
+
arr = []
|
393
|
+
filename = File.join(@git_dir, 'logs/refs/stash')
|
394
|
+
if File.exist?(filename)
|
395
|
+
File.open(filename).each_with_index { |line, i|
|
396
|
+
m = line.match(/:(.*)$/)
|
397
|
+
arr << [i, m[1].strip]
|
398
|
+
}
|
399
|
+
end
|
400
|
+
arr
|
401
|
+
end
|
402
|
+
|
403
|
+
def stash_save(message)
|
404
|
+
output = command('stash save', [message])
|
405
|
+
return false unless output.match(/HEAD is now at/)
|
406
|
+
return true
|
407
|
+
end
|
408
|
+
|
409
|
+
def stash_apply(id)
|
410
|
+
command('stash apply', [id])
|
411
|
+
# Already uptodate! ---???? What then
|
412
|
+
end
|
413
|
+
|
414
|
+
def stash_clear
|
415
|
+
command('stash clear')
|
416
|
+
end
|
417
|
+
|
418
|
+
def stash_list
|
419
|
+
command('stash list')
|
420
|
+
end
|
421
|
+
|
422
|
+
def branch_new(branch)
|
423
|
+
command('branch', branch)
|
424
|
+
end
|
425
|
+
|
426
|
+
def branch_delete(branch)
|
427
|
+
command('branch', ['-D', branch])
|
428
|
+
end
|
429
|
+
|
430
|
+
def checkout(branch, opts = {})
|
431
|
+
arr_opts = []
|
432
|
+
arr_opts << '-f' if opts[:force]
|
433
|
+
arr_opts << branch.to_s
|
434
|
+
|
435
|
+
command('checkout', arr_opts)
|
436
|
+
end
|
437
|
+
|
438
|
+
def merge(branch, message = nil)
|
439
|
+
arr_opts = []
|
440
|
+
arr_opts << ["-m '#{message}'"] if message
|
441
|
+
arr_opts << branch.to_a.join(' ')
|
442
|
+
command('merge', arr_opts)
|
443
|
+
end
|
444
|
+
|
445
|
+
def unmerged
|
446
|
+
unmerged = []
|
447
|
+
command_lines('diff', ["--cached"]).each do |line|
|
448
|
+
unmerged << $1 if line =~ /^\* Unmerged path (.*)/
|
449
|
+
end
|
450
|
+
unmerged
|
451
|
+
end
|
452
|
+
|
453
|
+
def conflicts #yields :file, :your, :their
|
454
|
+
self.unmerged.each do |f|
|
455
|
+
your = Tempfile.new("YOUR-#{File.basename(f)}").path
|
456
|
+
arr_opts = [":2:#{f}", ">#{your}"]
|
457
|
+
command('show', arr_opts)
|
458
|
+
|
459
|
+
their = Tempfile.new("THEIR-#{File.basename(f)}").path
|
460
|
+
arr_opts = [":3:#{f}", ">#{their}"]
|
461
|
+
command('show', arr_opts)
|
462
|
+
yield(f, your, their)
|
463
|
+
end
|
464
|
+
end
|
465
|
+
|
466
|
+
def remote_add(name, url, opts = {})
|
467
|
+
arr_opts = ['add']
|
468
|
+
arr_opts << '-f' if opts[:with_fetch]
|
469
|
+
arr_opts << name
|
470
|
+
arr_opts << url
|
471
|
+
|
472
|
+
command('remote', arr_opts)
|
473
|
+
end
|
474
|
+
|
475
|
+
# this is documented as such, but seems broken for some reason
|
476
|
+
# i'll try to get around it some other way later
|
477
|
+
def remote_remove(name)
|
478
|
+
command('remote', ['rm', name])
|
479
|
+
end
|
480
|
+
|
481
|
+
def remotes
|
482
|
+
command_lines('remote')
|
483
|
+
end
|
484
|
+
|
485
|
+
def tags
|
486
|
+
command_lines('tag')
|
487
|
+
end
|
488
|
+
|
489
|
+
def tag(tag)
|
490
|
+
command('tag', tag)
|
491
|
+
end
|
492
|
+
|
493
|
+
|
494
|
+
def fetch(remote)
|
495
|
+
command('fetch', remote.to_s)
|
496
|
+
end
|
497
|
+
|
498
|
+
def push(remote, branch = 'master')
|
499
|
+
command('push', [remote.to_s, branch.to_s])
|
500
|
+
end
|
501
|
+
|
502
|
+
def tag_sha(tag_name)
|
503
|
+
head = File.join(@git_dir, 'refs', 'tags', tag_name)
|
504
|
+
return File.read(head).chomp if File.exists?(head)
|
505
|
+
|
506
|
+
command('show-ref', ['--tags', '-s', tag_name])
|
507
|
+
end
|
508
|
+
|
509
|
+
def repack
|
510
|
+
command('repack', ['-a', '-d'])
|
511
|
+
end
|
512
|
+
|
513
|
+
# reads a tree into the current index file
|
514
|
+
def read_tree(treeish, opts = {})
|
515
|
+
arr_opts = []
|
516
|
+
arr_opts << "--prefix=#{opts[:prefix]}" if opts[:prefix]
|
517
|
+
arr_opts << treeish.to_a.join(' ')
|
518
|
+
command('read-tree', arr_opts)
|
519
|
+
end
|
520
|
+
|
521
|
+
def write_tree
|
522
|
+
command('write-tree')
|
523
|
+
end
|
524
|
+
|
525
|
+
def commit_tree(tree, opts = {})
|
526
|
+
opts[:message] = "commit tree #{tree}" if !opts[:message]
|
527
|
+
t = Tempfile.new('commit-message')
|
528
|
+
t.write(opts[:message])
|
529
|
+
t.close
|
530
|
+
|
531
|
+
arr_opts = []
|
532
|
+
arr_opts << tree
|
533
|
+
arr_opts << "-p #{opts[:parent]}" if opts[:parent]
|
534
|
+
opts[:parents].each { |p| arr_opts << "-p #{p.to_s}" } if opts[:parents]
|
535
|
+
arr_opts << "< #{t.path}"
|
536
|
+
command('commit-tree', arr_opts)
|
537
|
+
end
|
538
|
+
|
539
|
+
def update_ref(branch, commit)
|
540
|
+
command('update-ref', [branch.to_s, commit.to_s])
|
541
|
+
end
|
542
|
+
|
543
|
+
def checkout_index(opts = {})
|
544
|
+
arr_opts = []
|
545
|
+
arr_opts << "--prefix=#{opts[:prefix]}" if opts[:prefix]
|
546
|
+
arr_opts << "--force" if opts[:force]
|
547
|
+
arr_opts << "--all" if opts[:all]
|
548
|
+
arr_opts << ('-- ' + opts[:path_limiter]) if opts[:path_limiter].is_a? String
|
549
|
+
command('checkout-index', arr_opts)
|
550
|
+
end
|
551
|
+
|
552
|
+
# creates an archive file
|
553
|
+
#
|
554
|
+
# options
|
555
|
+
# :format (zip, tar)
|
556
|
+
# :prefix
|
557
|
+
# :remote
|
558
|
+
# :path
|
559
|
+
def archive(sha, file = nil, opts = {})
|
560
|
+
opts[:format] = 'zip' if !opts[:format]
|
561
|
+
|
562
|
+
if opts[:format] == 'tgz'
|
563
|
+
opts[:format] = 'tar'
|
564
|
+
opts[:add_gzip] = true
|
565
|
+
end
|
566
|
+
|
567
|
+
if !file
|
568
|
+
file = Tempfile.new('archive').path
|
569
|
+
end
|
570
|
+
|
571
|
+
arr_opts = []
|
572
|
+
arr_opts << "--format=#{opts[:format]}" if opts[:format]
|
573
|
+
arr_opts << "--prefix=#{opts[:prefix]}" if opts[:prefix]
|
574
|
+
arr_opts << "--remote=#{opts[:remote]}" if opts[:remote]
|
575
|
+
arr_opts << sha
|
576
|
+
arr_opts << opts[:path] if opts[:path]
|
577
|
+
arr_opts << '| gzip' if opts[:add_gzip]
|
578
|
+
arr_opts << "> #{file.to_s}"
|
579
|
+
command('archive', arr_opts)
|
580
|
+
return file
|
581
|
+
end
|
582
|
+
|
583
|
+
private
|
584
|
+
|
585
|
+
def command_lines(cmd, opts = [], chdir = true)
|
586
|
+
command(cmd, opts, chdir).split("\n")
|
587
|
+
end
|
588
|
+
|
589
|
+
def command(cmd, opts = [], chdir = true)
|
590
|
+
ENV['GIT_DIR'] = @git_dir if (@git_dir != ENV['GIT_DIR'])
|
591
|
+
ENV['GIT_INDEX_FILE'] = @git_index_file if (@git_index_file != ENV['GIT_INDEX_FILE'])
|
592
|
+
ENV['GIT_WORK_TREE'] = @git_work_dir if (@git_work_dir != ENV['GIT_WORK_TREE'])
|
593
|
+
path = @git_work_dir || @git_dir || @path
|
594
|
+
|
595
|
+
opts = opts.to_a.join(' ')
|
596
|
+
git_cmd = "git #{cmd} #{opts}"
|
597
|
+
|
598
|
+
out = nil
|
599
|
+
if chdir && (Dir.getwd != path)
|
600
|
+
Dir.chdir(path) { out = `#{git_cmd} 2>&1`.chomp }
|
601
|
+
else
|
602
|
+
out = `#{git_cmd} 2>&1`.chomp
|
603
|
+
end
|
604
|
+
|
605
|
+
if @logger
|
606
|
+
@logger.info(git_cmd)
|
607
|
+
@logger.debug(out)
|
608
|
+
end
|
609
|
+
|
610
|
+
if $?.exitstatus > 0
|
611
|
+
if $?.exitstatus == 1 && out == ''
|
612
|
+
return ''
|
613
|
+
end
|
614
|
+
raise Git::GitExecuteError.new(git_cmd + ':' + out.to_s)
|
615
|
+
end
|
616
|
+
out
|
617
|
+
end
|
618
|
+
|
619
|
+
end
|
620
|
+
end
|