# File lib/git/lib.rb, line 10
10: def initialize(base = nil, logger = nil)
11: @git_dir = nil
12: @git_index_file = nil
13: @git_work_dir = nil
14: @path = nil
15:
16: if base.is_a?(Git::Base)
17: @git_dir = base.repo.path
18: @git_index_file = base.index.path if base.index
19: @git_work_dir = base.dir.path if base.dir
20: elsif base.is_a?(Hash)
21: @git_dir = base[:repository]
22: @git_index_file = base[:index]
23: @git_work_dir = base[:working_directory]
24: end
25: @logger = logger
26: end
# File lib/git/lib.rb, line 395
395: def add(path = '.')
396: arr_opts = ['--']
397: if path.is_a?(Array)
398: arr_opts += path
399: else
400: arr_opts << path
401: end
402: command('add', arr_opts)
403: end
# File lib/git/lib.rb, line 433
433: def apply(patch_file)
434: arr_opts = []
435: arr_opts << '--' << patch_file if patch_file
436: command('apply', arr_opts)
437: end
# File lib/git/lib.rb, line 439
439: def apply_mail(patch_file)
440: arr_opts = []
441: arr_opts << '--' << patch_file if patch_file
442: command('am', arr_opts)
443: end
creates an archive file
options
:format (zip, tar) :prefix :remote :path
# File lib/git/lib.rb, line 627
627: def archive(sha, file = nil, opts = {})
628: opts[:format] ||= 'zip'
629:
630: if opts[:format] == 'tgz'
631: opts[:format] = 'tar'
632: opts[:add_gzip] = true
633: end
634:
635: file ||= Tempfile.new('archive').path
636:
637: arr_opts = []
638: arr_opts << "--format=#{opts[:format]}" if opts[:format]
639: arr_opts << "--prefix=#{opts[:prefix]}" if opts[:prefix]
640: arr_opts << "--remote=#{opts[:remote]}" if opts[:remote]
641: arr_opts << sha
642: arr_opts << '--' << opts[:path] if opts[:path]
643: command('archive', arr_opts, true, (opts[:add_gzip] ? '| gzip' : '') + " > #{escape file}")
644: return file
645: end
# File lib/git/lib.rb, line 214
214: def branch_current
215: branches_all.select { |b| b[1] }.first[0] rescue nil
216: end
# File lib/git/lib.rb, line 482
482: def branch_delete(branch)
483: command('branch', ['-D', branch])
484: end
# File lib/git/lib.rb, line 478
478: def branch_new(branch)
479: command('branch', branch)
480: end
# File lib/git/lib.rb, line 198
198: def branches_all
199: arr = []
200: command_lines('branch', '-a').each do |b|
201: current = (b[0, 2] == '* ')
202: arr << [b.gsub('* ', '').strip, current]
203: end
204: arr
205: end
# File lib/git/lib.rb, line 194
194: def change_head_branch(branch_name)
195: command('symbolic-ref', ['HEAD', "refs/heads/#{branch_name}"])
196: end
# File lib/git/lib.rb, line 486
486: def checkout(branch, opts = {})
487: arr_opts = []
488: arr_opts << '-f' if opts[:force]
489: arr_opts << '-b' << opts[:new_branch] if opts[:new_branch]
490: arr_opts << branch
491:
492: command('checkout', arr_opts)
493: end
# File lib/git/lib.rb, line 495
495: def checkout_file(version, file)
496: arr_opts = []
497: arr_opts << version
498: arr_opts << file
499: command('checkout', arr_opts)
500: end
# File lib/git/lib.rb, line 610
610: def checkout_index(opts = {})
611: arr_opts = []
612: arr_opts << "--prefix=#{opts[:prefix]}" if opts[:prefix]
613: arr_opts << "--force" if opts[:force]
614: arr_opts << "--all" if opts[:all]
615: arr_opts << '--' << opts[:path_limiter] if opts[:path_limiter].is_a? String
616:
617: command('checkout-index', arr_opts)
618: end
tries to clone the given repo
returns {:repository} (if bare)
{:working_directory} otherwise
accepts options:
:remote:: name of remote (rather than 'origin') :bare:: no working directory :depth:: the number of commits back to pull
TODO - make this work with SSH password or auth_key
# File lib/git/lib.rb, line 44
44: def clone(repository, name, opts = {})
45: @path = opts[:path] || '.'
46: clone_dir = opts[:path] ? File.join(@path, name) : name
47:
48: arr_opts = []
49: arr_opts << "--bare" if opts[:bare]
50: arr_opts << "-o" << opts[:remote] if opts[:remote]
51: arr_opts << "--depth" << opts[:depth].to_i if opts[:depth] && opts[:depth].to_i > 0
52:
53: arr_opts << '--'
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
# File lib/git/lib.rb, line 418
418: def commit(message, opts = {})
419: arr_opts = ['-m', message]
420: arr_opts << '-a' if opts[:add_all]
421: arr_opts << '--allow-empty' if opts[:allow_empty]
422: arr_opts << "--author" << opts[:author] if opts[:author]
423: command('commit', arr_opts)
424: end
returns useful array of raw commit object data
# File lib/git/lib.rb, line 120
120: def commit_data(sha)
121: sha = sha.to_s
122: cdata = command_lines('cat-file', ['commit', sha])
123: process_commit_data(cdata, sha, 0)
124: end
# File lib/git/lib.rb, line 593
593: def commit_tree(tree, opts = {})
594: opts[:message] ||= "commit tree #{tree}"
595: t = Tempfile.new('commit-message')
596: t.write(opts[:message])
597: t.close
598:
599: arr_opts = []
600: arr_opts << tree
601: arr_opts << '-p' << opts[:parent] if opts[:parent]
602: arr_opts += [opts[:parents]].map { |p| ['-p', p] }.flatten if opts[:parents]
603: command('commit-tree', arr_opts, true, "< #{escape t.path}")
604: end
# File lib/git/lib.rb, line 323
323: def config_get(name)
324: do_get = lambda do
325: command('config', ['--get', name])
326: end
327:
328: if @git_dir
329: Dir.chdir(@git_dir, &do_get)
330: else
331: build_list.call
332: end
333: end
# File lib/git/lib.rb, line 339
339: def config_list
340: build_list = lambda do |path|
341: parse_config_list command_lines('config', ['--list'])
342: end
343:
344: if @git_dir
345: Dir.chdir(@git_dir, &build_list)
346: else
347: build_list.call
348: end
349: end
# File lib/git/lib.rb, line 313
313: def config_remote(name)
314: hsh = {}
315: config_list.each do |key, value|
316: if /remote.#{name}/.match(key)
317: hsh[key.gsub("remote.#{name}.", '')] = value
318: end
319: end
320: hsh
321: end
WRITE COMMANDS ##
# File lib/git/lib.rb, line 387
387: def config_set(name, value)
388: command('config', [name, value])
389: end
# File lib/git/lib.rb, line 517
517: def conflicts # :yields: file, your, their
518: self.unmerged.each do |f|
519: your = Tempfile.new("YOUR-#{File.basename(f)}").path
520: command('show', ":2:#{f}", true, "> #{escape your}")
521:
522: their = Tempfile.new("THEIR-#{File.basename(f)}").path
523: command('show', ":3:#{f}", true, "> #{escape their}")
524: yield(f, your, their)
525: end
526: end
returns the current version of git, as an Array of Fixnums.
# File lib/git/lib.rb, line 648
648: def current_command_version
649: output = command('version', [], false)
650: version = output[/\d+\.\d+(\.\d+)+/]
651: version.split('.').collect {|i| i.to_i}
652: end
compares the index and the working directory
# File lib/git/lib.rb, line 273
273: def diff_files
274: hsh = {}
275: command_lines('diff-files').each do |line|
276: (info, file) = line.split("\t")
277: (mode_src, mode_dest, sha_src, sha_dest, type) = info.split
278: hsh[file] = {:path => file, :mode_file => mode_src.to_s[1, 7], :mode_index => mode_dest,
279: :sha_file => sha_src, :sha_index => sha_dest, :type => type}
280: end
281: hsh
282: end
# File lib/git/lib.rb, line 243
243: def diff_full(obj1 = 'HEAD', obj2 = nil, opts = {})
244: diff_opts = ['-p']
245: diff_opts << obj1
246: diff_opts << obj2 if obj2.is_a?(String)
247: diff_opts << '--' << opts[:path_limiter] if opts[:path_limiter].is_a? String
248:
249: command('diff', diff_opts)
250: end
compares the index and the repository
# File lib/git/lib.rb, line 285
285: def diff_index(treeish)
286: hsh = {}
287: command_lines('diff-index', treeish).each do |line|
288: (info, file) = line.split("\t")
289: (mode_src, mode_dest, sha_src, sha_dest, type) = info.split
290: hsh[file] = {:path => file, :mode_repo => mode_src.to_s[1, 7], :mode_index => mode_dest,
291: :sha_repo => sha_src, :sha_index => sha_dest, :type => type}
292: end
293: hsh
294: end
# File lib/git/lib.rb, line 252
252: def diff_stats(obj1 = 'HEAD', obj2 = nil, opts = {})
253: diff_opts = ['--numstat']
254: diff_opts << obj1
255: diff_opts << obj2 if obj2.is_a?(String)
256: diff_opts << '--' << opts[:path_limiter] if opts[:path_limiter].is_a? String
257:
258: hsh = {:total => {:insertions => 0, :deletions => 0, :lines => 0, :files => 0}, :files => {}}
259:
260: command_lines('diff', diff_opts).each do |file|
261: (insertions, deletions, filename) = file.split("\t")
262: hsh[:total][:insertions] += insertions.to_i
263: hsh[:total][:deletions] += deletions.to_i
264: hsh[:total][:lines] = (hsh[:total][:deletions] + hsh[:total][:insertions])
265: hsh[:total][:files] += 1
266: hsh[:files][filename] = {:insertions => insertions.to_i, :deletions => deletions.to_i}
267: end
268:
269: hsh
270: end
# File lib/git/lib.rb, line 557
557: def fetch(remote)
558: command('fetch', remote)
559: end
# File lib/git/lib.rb, line 80
80: def full_log_commits(opts = {})
81: arr_opts = ['--pretty=raw']
82: arr_opts << "-#{opts[:count]}" if opts[:count]
83: arr_opts << "--skip=#{opts[:skip]}" if opts[:skip]
84: arr_opts << "--since=#{opts[:since]}" if opts[:since].is_a? String
85: arr_opts << "--until=#{opts[:until]}" if opts[:until].is_a? String
86: arr_opts << "--grep=#{opts[:grep]}" if opts[:grep].is_a? String
87: arr_opts << "--author=#{opts[:author]}" if opts[:author].is_a? String
88: arr_opts << "#{opts[:between][0].to_s}..#{opts[:between][1].to_s}" if (opts[:between] && opts[:between].size == 2)
89: arr_opts << opts[:object] if opts[:object].is_a? String
90: arr_opts << '--' << opts[:path_limiter] if opts[:path_limiter].is_a? String
91:
92: full_log = command_lines('log', arr_opts, true)
93: process_commit_data(full_log)
94: end
# File lib/git/lib.rb, line 186
186: def full_tree(sha)
187: command_lines('ls-tree', ['-r', sha])
188: end
# File lib/git/lib.rb, line 577
577: def gc
578: command('gc', ['--prune', '--aggressive', '--auto'])
579: end
# File lib/git/lib.rb, line 335
335: def global_config_get(name)
336: command('config', ['--global', '--get', name], false)
337: end
# File lib/git/lib.rb, line 351
351: def global_config_list
352: parse_config_list command_lines('config', ['--global', '--list'], false)
353: end
# File lib/git/lib.rb, line 391
391: def global_config_set(name, value)
392: command('config', ['--global', name, value], false)
393: end
returns hash
# File lib/git/lib.rb, line 222
222: def grep(string, opts = {})
223: opts[:object] ||= 'HEAD'
224:
225: grep_opts = ['-n']
226: grep_opts << '-i' if opts[:ignore_case]
227: grep_opts << '-v' if opts[:invert_match]
228: grep_opts << '-e'
229: grep_opts << string
230: grep_opts << opts[:object] if opts[:object].is_a?(String)
231: grep_opts << '--' << opts[:path_limiter] if opts[:path_limiter].is_a? String
232:
233: hsh = {}
234: command_lines('grep', grep_opts).each do |line|
235: if m = /(.*)\:(\d+)\:(.*)/.match(line)
236: hsh[m[1]] ||= []
237: hsh[m[1]] << [m[2].to_i, m[3]]
238: end
239: end
240: hsh
241: end
# File lib/git/lib.rb, line 308
308: def ignored_files
309: command_lines('ls-files', ['--others', '-i', '--exclude-standard'])
310: end
# File lib/git/lib.rb, line 28
28: def init
29: command('init')
30: end
# File lib/git/lib.rb, line 207
207: def list_files(ref_dir)
208: dir = File.join(@git_dir, 'refs', ref_dir)
209: files = []
210: Dir.chdir(dir) { files = Dir.glob('**/*').select { |f| File.file?(f) } } rescue nil
211: files
212: end
READ COMMANDS ##
# File lib/git/lib.rb, line 66
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 << "--until=#{opts[:until]}" if opts[:until].is_a? String
71: arr_opts << "--grep=#{opts[:grep]}" if opts[:grep].is_a? String
72: arr_opts << "--author=#{opts[:author]}" if opts[:author].is_a? String
73: arr_opts << "#{opts[:between][0].to_s}..#{opts[:between][1].to_s}" if (opts[:between] && opts[:between].size == 2)
74: arr_opts << opts[:object] if opts[:object].is_a? String
75: arr_opts << '--' << opts[:path_limiter] if opts[:path_limiter].is_a? String
76:
77: command_lines('log', arr_opts, true).map { |l| l.split.first }
78: end
# File lib/git/lib.rb, line 296
296: def ls_files(location=nil)
297: hsh = {}
298: command_lines('ls-files', ['--stage', location]).each do |line|
299: (info, file) = line.split("\t")
300: (mode, sha, stage) = info.split
301: file = eval(file) if file =~ /^\".*\"$/ # This takes care of quoted strings returned from git
302: hsh[file] = {:path => file, :mode_index => mode, :sha_index => sha, :stage => stage}
303: end
304: hsh
305: end
# File lib/git/lib.rb, line 170
170: def ls_tree(sha)
171: data = {'blob' => {}, 'tree' => {}}
172:
173: command_lines('ls-tree', sha).each do |line|
174: (info, filenm) = line.split("\t")
175: (mode, type, sha) = info.split
176: data[type][filenm] = {:mode => mode, :sha => sha}
177: end
178:
179: data
180: end
# File lib/git/lib.rb, line 658
658: def meets_required_version?
659: current_version = self.current_command_version
660: required_version = self.required_command_version
661:
662: return current_version[0] >= required_version[0] &&
663: current_version[1] >= required_version[1] &&
664: (current_version[2] ? current_version[2] >= required_version[2] : true) &&
665: (current_version[3] ? current_version[3] >= required_version[3] : true)
666: end
# File lib/git/lib.rb, line 502
502: def merge(branch, message = nil)
503: arr_opts = []
504: arr_opts << '-m' << message if message
505: arr_opts += [branch]
506: command('merge', arr_opts)
507: end
# File lib/git/lib.rb, line 182
182: def mv(file1, file2)
183: command_lines('mv', ['--', file1, file2])
184: end
# File lib/git/lib.rb, line 107
107: def namerev(string)
108: command('name-rev', string).split[1]
109: end
# File lib/git/lib.rb, line 166
166: def object_contents(sha, &block)
167: command('cat-file', ['-p', sha], &block)
168: end
# File lib/git/lib.rb, line 115
115: def object_size(sha)
116: command('cat-file', ['-s', sha]).to_i
117: end
# File lib/git/lib.rb, line 111
111: def object_type(sha)
112: command('cat-file', ['-t', sha])
113: end
# File lib/git/lib.rb, line 364
364: def parse_config(file)
365: hsh = {}
366: parse_config_list command_lines('config', ['--list', '--file', file], false)
367: #hsh = {}
368: #file = File.expand_path(file)
369: #if File.file?(file)
370: # current_section = nil
371: # File.readlines(file).each do |line|
372: # if m = /\[(\w+)\]/.match(line)
373: # current_section = m[1]
374: # elsif m = /\[(\w+?) "(.*?)"\]/.match(line)
375: # current_section = "#{m[1]}.#{m[2]}"
376: # elsif m = /(\w+?) = (.*)/.match(line)
377: # key = "#{current_section}.#{m[1]}"
378: # hsh[key] = m[2]
379: # end
380: # end
381: #end
382: #hsh
383: end
# File lib/git/lib.rb, line 355
355: def parse_config_list(lines)
356: hsh = {}
357: lines.each do |line|
358: (key, *values) = line.split('=')
359: hsh[key] = values.join('=')
360: end
361: hsh
362: end
# File lib/git/lib.rb, line 126
126: def process_commit_data(data, sha = nil, indent = 4)
127: in_message = false
128:
129: if sha
130: hsh = {'sha' => sha, 'message' => '', 'parent' => []}
131: else
132: hsh_array = []
133: end
134:
135: data.each do |line|
136: line = line.chomp
137: if line == ''
138: in_message = !in_message
139: elsif in_message
140: hsh['message'] << line[indent..1] << "\n"
141: else
142: data = line.split
143: key = data.shift
144: value = data.join(' ')
145: if key == 'commit'
146: sha = value
147: hsh_array << hsh if hsh
148: hsh = {'sha' => sha, 'message' => '', 'parent' => []}
149: end
150: if key == 'parent'
151: hsh[key] << value
152: else
153: hsh[key] = value
154: end
155: end
156: end
157:
158: if hsh_array
159: hsh_array << hsh if hsh
160: hsh_array
161: else
162: hsh
163: end
164: end
# File lib/git/lib.rb, line 561
561: def push(remote, branch = 'master', tags = false)
562: command('push', [remote, branch])
563: command('push', ['--tags', remote]) if tags
564: end
reads a tree into the current index file
# File lib/git/lib.rb, line 582
582: def read_tree(treeish, opts = {})
583: arr_opts = []
584: arr_opts << "--prefix=#{opts[:prefix]}" if opts[:prefix]
585: arr_opts += [treeish]
586: command('read-tree', arr_opts)
587: end
# File lib/git/lib.rb, line 528
528: def remote_add(name, url, opts = {})
529: arr_opts = ['add']
530: arr_opts << '-f' if opts[:with_fetch]
531: arr_opts << '--'
532: arr_opts << name
533: arr_opts << url
534:
535: command('remote', arr_opts)
536: end
this is documented as such, but seems broken for some reason i’ll try to get around it some other way later
# File lib/git/lib.rb, line 540
540: def remote_remove(name)
541: command('remote', ['rm', '--', name])
542: end
# File lib/git/lib.rb, line 544
544: def remotes
545: command_lines('remote')
546: end
# File lib/git/lib.rb, line 405
405: def remove(path = '.', opts = {})
406: arr_opts = ['-f'] # overrides the up-to-date check by default
407: arr_opts << ['-r'] if opts[:recursive]
408: arr_opts << '--'
409: if path.is_a?(Array)
410: arr_opts += path
411: else
412: arr_opts << path
413: end
414:
415: command('rm', arr_opts)
416: end
# File lib/git/lib.rb, line 573
573: def repack
574: command('repack', ['-a', '-d'])
575: end
# File lib/git/lib.rb, line 654
654: def required_command_version
655: [1, 6, 0, 0]
656: end
# File lib/git/lib.rb, line 426
426: def reset(commit, opts = {})
427: arr_opts = []
428: arr_opts << '--hard' if opts[:hard]
429: arr_opts << commit if commit
430: command('reset', arr_opts)
431: end
# File lib/git/lib.rb, line 96
96: def revparse(string)
97: return string if string =~ /[A-Fa-f0-9]{40}/ # passing in a sha - just no-op it
98: rev = ['head', 'remotes', 'tags'].map do |d|
99: File.join(@git_dir, 'refs', d, string)
100: end.find do |path|
101: File.file?(path)
102: end
103: return File.read(rev).chomp if rev
104: command('rev-parse', string)
105: end
# File lib/git/lib.rb, line 462
462: def stash_apply(id = nil)
463: if id
464: command('stash apply', [id])
465: else
466: command('stash apply')
467: end
468: end
# File lib/git/lib.rb, line 470
470: def stash_clear
471: command('stash clear')
472: end
# File lib/git/lib.rb, line 474
474: def stash_list
475: command('stash list')
476: end
# File lib/git/lib.rb, line 457
457: def stash_save(message)
458: output = command('stash save', ['--', message])
459: output =~ /HEAD is now at/
460: end
# File lib/git/lib.rb, line 445
445: def stashes_all
446: arr = []
447: filename = File.join(@git_dir, 'logs/refs/stash')
448: if File.exist?(filename)
449: File.open(filename).each_with_index { |line, i|
450: m = line.match(/:(.*)$/)
451: arr << [i, m[1].strip]
452: }
453: end
454: arr
455: end
# File lib/git/lib.rb, line 552
552: def tag(tag)
553: command('tag', tag)
554: end
# File lib/git/lib.rb, line 566
566: def tag_sha(tag_name)
567: head = File.join(@git_dir, 'refs', 'tags', tag_name)
568: return File.read(head).chomp if File.exists?(head)
569:
570: command('show-ref', ['--tags', '-s', tag_name])
571: end
# File lib/git/lib.rb, line 190
190: def tree_depth(sha)
191: full_tree(sha).size
192: end
# File lib/git/lib.rb, line 509
509: def unmerged
510: unmerged = []
511: command_lines('diff', ["--cached"]).each do |line|
512: unmerged << $1 if line =~ /^\* Unmerged path (.*)/
513: end
514: unmerged
515: end
# File lib/git/lib.rb, line 675
675: def command(cmd, opts = [], chdir = true, redirect = '', &block)
676: ENV['GIT_DIR'] = @git_dir
677: ENV['GIT_INDEX_FILE'] = @git_index_file
678: ENV['GIT_WORK_TREE'] = @git_work_dir
679: path = @git_work_dir || @git_dir || @path
680:
681: opts = [opts].flatten.map {|s| escape(s) }.join(' ')
682: git_cmd = "git #{cmd} #{opts} #{redirect} 2>&1"
683:
684: out = nil
685: if chdir && (Dir.getwd != path)
686: Dir.chdir(path) { out = run_command(git_cmd, &block) }
687: else
688: out = run_command(git_cmd, &block)
689: end
690:
691: if @logger
692: @logger.info(git_cmd)
693: @logger.debug(out)
694: end
695:
696: if $?.exitstatus > 0
697: if $?.exitstatus == 1 && out == ''
698: return ''
699: end
700: raise Git::GitExecuteError.new(git_cmd + ':' + out.to_s)
701: end
702: out
703: end
# File lib/git/lib.rb, line 671
671: def command_lines(cmd, opts = [], chdir = true, redirect = '')
672: command(cmd, opts, chdir).split("\n")
673: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.