git 1.2.5 → 1.2.6
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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +255 -0
- data/lib/git.rb +54 -62
- data/lib/git/base.rb +82 -21
- data/lib/git/branch.rb +27 -9
- data/lib/git/branches.rb +25 -2
- data/lib/git/lib.rb +149 -77
- data/lib/git/log.rb +11 -0
- data/lib/git/object.rb +3 -1
- data/lib/git/path.rb +12 -8
- data/lib/git/remote.rb +0 -4
- data/lib/git/repository.rb +2 -0
- data/lib/git/version.rb +7 -0
- metadata +76 -38
- data/README +0 -240
data/lib/git/base.rb
CHANGED
@@ -16,19 +16,23 @@ module Git
|
|
16
16
|
# initializes a git repository
|
17
17
|
#
|
18
18
|
# options:
|
19
|
+
# :bare
|
20
|
+
# :index
|
19
21
|
# :repository
|
20
|
-
# :index_file
|
21
22
|
#
|
22
23
|
def self.init(working_dir, opts = {})
|
23
|
-
opts =
|
24
|
-
|
25
|
-
:repository => File.join(working_dir, '.git')
|
26
|
-
}.merge(opts)
|
24
|
+
opts[:working_directory] = working_dir if !opts[:working_directory]
|
25
|
+
opts[:repository] = File.join(opts[:working_directory], '.git') if !opts[:repository]
|
27
26
|
|
28
27
|
FileUtils.mkdir_p(opts[:working_directory]) if opts[:working_directory] && !File.directory?(opts[:working_directory])
|
29
28
|
|
30
|
-
|
31
|
-
|
29
|
+
init_opts = {
|
30
|
+
:bare => opts[:bare]
|
31
|
+
}
|
32
|
+
|
33
|
+
opts.delete(:working_directory) if opts[:bare]
|
34
|
+
|
35
|
+
Git::Lib.new(opts).init(init_opts)
|
32
36
|
|
33
37
|
self.new(opts)
|
34
38
|
end
|
@@ -115,11 +119,9 @@ module Git
|
|
115
119
|
|
116
120
|
# returns the repository size in bytes
|
117
121
|
def repo_size
|
118
|
-
size = 0
|
119
122
|
Dir.chdir(repo.path) do
|
120
|
-
|
123
|
+
return `du -s`.chomp.split.first.to_i
|
121
124
|
end
|
122
|
-
size.to_i
|
123
125
|
end
|
124
126
|
|
125
127
|
#g.config('user.name', 'Scott Chacon') # sets value
|
@@ -243,9 +245,23 @@ module Git
|
|
243
245
|
Git::Diff.new(self, objectish, obj2)
|
244
246
|
end
|
245
247
|
|
246
|
-
#
|
247
|
-
|
248
|
-
|
248
|
+
# updates the repository index using the workig dorectory content
|
249
|
+
#
|
250
|
+
# @git.add('path/to/file')
|
251
|
+
# @git.add(['path/to/file1','path/to/file2'])
|
252
|
+
# @git.add(:all => true)
|
253
|
+
#
|
254
|
+
# options:
|
255
|
+
# :all => true
|
256
|
+
#
|
257
|
+
# @param [String,Array] paths files paths to be added (optional, default='.')
|
258
|
+
# @param [Hash] options
|
259
|
+
def add(*args)
|
260
|
+
if args[0].instance_of?(String) || args[0].instance_of?(Array)
|
261
|
+
self.lib.add(args[0],args[1]||{})
|
262
|
+
else
|
263
|
+
self.lib.add('.', args[0]||{})
|
264
|
+
end
|
249
265
|
end
|
250
266
|
|
251
267
|
# removes file(s) from the git repository
|
@@ -264,12 +280,34 @@ module Git
|
|
264
280
|
self.lib.reset(commitish, opts)
|
265
281
|
end
|
266
282
|
|
283
|
+
# cleans the working directory
|
284
|
+
#
|
285
|
+
# options:
|
286
|
+
# :force
|
287
|
+
# :d
|
288
|
+
#
|
289
|
+
def clean(opts = {})
|
290
|
+
self.lib.clean(opts)
|
291
|
+
end
|
292
|
+
|
293
|
+
# reverts the working directory to the provided commitish.
|
294
|
+
# Accepts a range, such as comittish..HEAD
|
295
|
+
#
|
296
|
+
# options:
|
297
|
+
# :no_edit
|
298
|
+
#
|
299
|
+
def revert(commitish = nil, opts = {})
|
300
|
+
self.lib.revert(commitish, opts)
|
301
|
+
end
|
302
|
+
|
267
303
|
# commits all pending changes in the index file to the git repository
|
268
304
|
#
|
269
305
|
# options:
|
270
|
-
# :
|
306
|
+
# :all
|
271
307
|
# :allow_empty
|
308
|
+
# :amend
|
272
309
|
# :author
|
310
|
+
#
|
273
311
|
def commit(message, opts = {})
|
274
312
|
self.lib.commit(message, opts)
|
275
313
|
end
|
@@ -319,10 +357,14 @@ module Git
|
|
319
357
|
self.lib.conflicts(&block)
|
320
358
|
end
|
321
359
|
|
322
|
-
#
|
323
|
-
|
324
|
-
|
325
|
-
|
360
|
+
# pulls the given branch from the given remote into the current branch
|
361
|
+
#
|
362
|
+
# @git.pull # pulls from origin/master
|
363
|
+
# @git.pull('upstream') # pulls from upstream/master
|
364
|
+
# @git.pull('upstream', 'develope') # pulls from upstream/develop
|
365
|
+
#
|
366
|
+
def pull(remote='origin', branch='master')
|
367
|
+
self.lib.pull(remote, branch)
|
326
368
|
end
|
327
369
|
|
328
370
|
# returns an array of Git:Remote objects
|
@@ -337,12 +379,22 @@ module Git
|
|
337
379
|
# @git.fetch('scotts_git')
|
338
380
|
# @git.merge('scotts_git/master')
|
339
381
|
#
|
382
|
+
# Options:
|
383
|
+
# :fetch => true
|
384
|
+
# :track => <branch_name>
|
340
385
|
def add_remote(name, url, opts = {})
|
341
386
|
url = url.repo.path if url.is_a?(Git::Base)
|
342
387
|
self.lib.remote_add(name, url, opts)
|
343
388
|
Git::Remote.new(self, name)
|
344
389
|
end
|
345
390
|
|
391
|
+
# removes a remote from this repository
|
392
|
+
#
|
393
|
+
# @git.remove_remote('scott_git')
|
394
|
+
def remove_remote(name)
|
395
|
+
self.lib.remote_remove(name)
|
396
|
+
end
|
397
|
+
|
346
398
|
# returns an array of all Git::Tag objects for this repository
|
347
399
|
def tags
|
348
400
|
self.lib.tags.map { |r| tag(r) }
|
@@ -394,9 +446,17 @@ module Git
|
|
394
446
|
end
|
395
447
|
|
396
448
|
def with_temp_index &blk
|
397
|
-
|
398
|
-
|
399
|
-
|
449
|
+
# Workaround for JRUBY, since they handle the TempFile path different.
|
450
|
+
# MUST be improved to be safer and OS independent.
|
451
|
+
if RUBY_PLATFORM == 'java'
|
452
|
+
temp_path = "/tmp/temp-index-#{(0...15).map{ ('a'..'z').to_a[rand(26)] }.join}"
|
453
|
+
else
|
454
|
+
tempfile = Tempfile.new('temp-index')
|
455
|
+
temp_path = tempfile.path
|
456
|
+
tempfile.close
|
457
|
+
tempfile.unlink
|
458
|
+
end
|
459
|
+
|
400
460
|
with_index(temp_path, &blk)
|
401
461
|
end
|
402
462
|
|
@@ -444,6 +504,7 @@ module Git
|
|
444
504
|
def with_temp_working &blk
|
445
505
|
tempfile = Tempfile.new("temp-workdir")
|
446
506
|
temp_dir = tempfile.path
|
507
|
+
tempfile.close
|
447
508
|
tempfile.unlink
|
448
509
|
Dir.mkdir(temp_dir, 0700)
|
449
510
|
with_working(temp_dir, &blk)
|
data/lib/git/branch.rb
CHANGED
@@ -1,22 +1,17 @@
|
|
1
|
+
require 'git/path'
|
2
|
+
|
1
3
|
module Git
|
4
|
+
|
2
5
|
class Branch < Path
|
3
6
|
|
4
7
|
attr_accessor :full, :remote, :name
|
5
8
|
|
6
9
|
def initialize(base, name)
|
7
|
-
@remote = nil
|
8
10
|
@full = name
|
9
11
|
@base = base
|
10
12
|
@gcommit = nil
|
11
13
|
@stashes = nil
|
12
|
-
|
13
|
-
parts = name.split('/')
|
14
|
-
if parts[1]
|
15
|
-
@remote = Git::Remote.new(@base, parts[0])
|
16
|
-
@name = parts[1]
|
17
|
-
else
|
18
|
-
@name = parts[0]
|
19
|
-
end
|
14
|
+
@remote, @name = parse_name(name)
|
20
15
|
end
|
21
16
|
|
22
17
|
def gcommit
|
@@ -100,5 +95,28 @@ module Git
|
|
100
95
|
@base.lib.branch_current == @name
|
101
96
|
end
|
102
97
|
|
98
|
+
# Given a full branch name return an Array containing the remote and branch names.
|
99
|
+
#
|
100
|
+
# Removes 'remotes' from the beggining of the name (if present).
|
101
|
+
# Takes the second part (splittign by '/') as the remote name.
|
102
|
+
# Takes the rest as the repo name (can also hold one or more '/').
|
103
|
+
#
|
104
|
+
# Example:
|
105
|
+
# parse_name('master') #=> [nil, 'master']
|
106
|
+
# parse_name('origin/master') #=> ['origin', 'master']
|
107
|
+
# parse_name('remotes/origin/master') #=> ['origin', 'master']
|
108
|
+
# parse_name('origin/master/v2') #=> ['origin', 'master/v2']
|
109
|
+
#
|
110
|
+
# param [String] name branch full name.
|
111
|
+
# return [<Git::Remote,NilClass,String>] an Array containing the remote and branch names.
|
112
|
+
def parse_name(name)
|
113
|
+
if name.match(/^(?:remotes)?\/([^\/]+)\/(.+)/)
|
114
|
+
return [Git::Remote.new(@base, $1), $2]
|
115
|
+
end
|
116
|
+
|
117
|
+
return [nil, name]
|
118
|
+
end
|
119
|
+
|
103
120
|
end
|
121
|
+
|
104
122
|
end
|
data/lib/git/branches.rb
CHANGED
@@ -2,6 +2,7 @@ module Git
|
|
2
2
|
|
3
3
|
# object that holds all the available branches
|
4
4
|
class Branches
|
5
|
+
|
5
6
|
include Enumerable
|
6
7
|
|
7
8
|
def initialize(base)
|
@@ -32,8 +33,29 @@ module Git
|
|
32
33
|
@branches.values.each(&block)
|
33
34
|
end
|
34
35
|
|
35
|
-
|
36
|
-
|
36
|
+
# Returns the target branch
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
# Given (git branch -a):
|
40
|
+
# master
|
41
|
+
# remotes/working/master
|
42
|
+
#
|
43
|
+
# g.branches['master'].full #=> 'master'
|
44
|
+
# g.branches['working/master'].full => 'remotes/working/master'
|
45
|
+
# g.branches['remotes/working/master'].full => 'remotes/working/master'
|
46
|
+
#
|
47
|
+
# @param [#to_s] branch_name the target branch name.
|
48
|
+
# @return [Git::Branch] the target branch.
|
49
|
+
def [](branch_name)
|
50
|
+
@branches.values.inject(@branches) do |branches, branch|
|
51
|
+
branches[branch.full] ||= branch
|
52
|
+
|
53
|
+
# This is how Git (version 1.7.9.5) works.
|
54
|
+
# Lets you ignore the 'remotes' if its at the beginning of the branch full name (even if is not a real remote branch).
|
55
|
+
branches[branch.full.sub('remotes/', '')] ||= branch if branch.full =~ /^remotes\/.+/
|
56
|
+
|
57
|
+
branches
|
58
|
+
end[branch_name.to_s]
|
37
59
|
end
|
38
60
|
|
39
61
|
def to_s
|
@@ -45,4 +67,5 @@ module Git
|
|
45
67
|
end
|
46
68
|
|
47
69
|
end
|
70
|
+
|
48
71
|
end
|
data/lib/git/lib.rb
CHANGED
@@ -24,9 +24,18 @@ module Git
|
|
24
24
|
end
|
25
25
|
@logger = logger
|
26
26
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
|
28
|
+
# creates or reinitializes the repository
|
29
|
+
#
|
30
|
+
# options:
|
31
|
+
# :bare
|
32
|
+
# :working_directory
|
33
|
+
#
|
34
|
+
def init(opts={})
|
35
|
+
arr_opts = []
|
36
|
+
arr_opts << '--bare' if opts[:bare]
|
37
|
+
|
38
|
+
command('init', arr_opts, false)
|
30
39
|
end
|
31
40
|
|
32
41
|
# tries to clone the given repo
|
@@ -35,9 +44,10 @@ module Git
|
|
35
44
|
# {:working_directory} otherwise
|
36
45
|
#
|
37
46
|
# accepts options:
|
38
|
-
# :remote::
|
39
|
-
# :bare::
|
40
|
-
# :
|
47
|
+
# :remote:: name of remote (rather than 'origin')
|
48
|
+
# :bare:: no working directory
|
49
|
+
# :recursive:: after the clone is created, initialize all submodules within, using their default settings.
|
50
|
+
# :depth:: the number of commits back to pull
|
41
51
|
#
|
42
52
|
# TODO - make this work with SSH password or auth_key
|
43
53
|
#
|
@@ -47,8 +57,10 @@ module Git
|
|
47
57
|
|
48
58
|
arr_opts = []
|
49
59
|
arr_opts << "--bare" if opts[:bare]
|
60
|
+
arr_opts << "--recursive" if opts[:recursive]
|
50
61
|
arr_opts << "-o" << opts[:remote] if opts[:remote]
|
51
62
|
arr_opts << "--depth" << opts[:depth].to_i if opts[:depth] && opts[:depth].to_i > 0
|
63
|
+
arr_opts << "--config" << opts[:config] if opts[:config]
|
52
64
|
|
53
65
|
arr_opts << '--'
|
54
66
|
arr_opts << repository
|
@@ -62,36 +74,29 @@ module Git
|
|
62
74
|
|
63
75
|
## READ COMMANDS ##
|
64
76
|
|
77
|
+
def log_commits(opts={})
|
78
|
+
arr_opts = log_common_options(opts)
|
65
79
|
|
66
|
-
|
67
|
-
|
68
|
-
arr_opts
|
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
|
80
|
+
arr_opts << '--pretty=oneline'
|
81
|
+
|
82
|
+
arr_opts += log_path_options(opts)
|
76
83
|
|
77
84
|
command_lines('log', arr_opts, true).map { |l| l.split.first }
|
78
85
|
end
|
79
86
|
|
80
|
-
def full_log_commits(opts
|
81
|
-
arr_opts =
|
82
|
-
|
87
|
+
def full_log_commits(opts={})
|
88
|
+
arr_opts = log_common_options(opts)
|
89
|
+
|
90
|
+
arr_opts << '--pretty=raw'
|
83
91
|
arr_opts << "--skip=#{opts[:skip]}" if opts[:skip]
|
84
|
-
|
85
|
-
arr_opts
|
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
|
92
|
+
|
93
|
+
arr_opts += log_path_options(opts)
|
91
94
|
|
92
95
|
full_log = command_lines('log', arr_opts, true)
|
93
96
|
process_commit_data(full_log)
|
94
97
|
end
|
98
|
+
|
99
|
+
|
95
100
|
|
96
101
|
def revparse(string)
|
97
102
|
return string if string =~ /[A-Fa-f0-9]{40}/ # passing in a sha - just no-op it
|
@@ -271,26 +276,12 @@ module Git
|
|
271
276
|
|
272
277
|
# compares the index and the working directory
|
273
278
|
def diff_files
|
274
|
-
|
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
|
279
|
+
diff_as_hash('diff-files')
|
282
280
|
end
|
283
281
|
|
284
282
|
# compares the index and the repository
|
285
283
|
def diff_index(treeish)
|
286
|
-
|
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
|
284
|
+
diff_as_hash('diff-index', treeish)
|
294
285
|
end
|
295
286
|
|
296
287
|
def ls_files(location=nil)
|
@@ -321,7 +312,7 @@ module Git
|
|
321
312
|
end
|
322
313
|
|
323
314
|
def config_get(name)
|
324
|
-
do_get = lambda do
|
315
|
+
do_get = lambda do |path|
|
325
316
|
command('config', ['--get', name])
|
326
317
|
end
|
327
318
|
|
@@ -362,24 +353,7 @@ module Git
|
|
362
353
|
end
|
363
354
|
|
364
355
|
def parse_config(file)
|
365
|
-
hsh = {}
|
366
356
|
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
357
|
end
|
384
358
|
|
385
359
|
## WRITE COMMANDS ##
|
@@ -391,14 +365,31 @@ module Git
|
|
391
365
|
def global_config_set(name, value)
|
392
366
|
command('config', ['--global', name, value], false)
|
393
367
|
end
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
368
|
+
|
369
|
+
# updates the repository index using the workig dorectory content
|
370
|
+
#
|
371
|
+
# lib.add('path/to/file')
|
372
|
+
# lib.add(['path/to/file1','path/to/file2'])
|
373
|
+
# lib.add(:all => true)
|
374
|
+
#
|
375
|
+
# options:
|
376
|
+
# :all => true
|
377
|
+
# :force => true
|
378
|
+
#
|
379
|
+
# @param [String,Array] paths files paths to be added to the repository
|
380
|
+
# @param [Hash] options
|
381
|
+
def add(paths='.',options={})
|
382
|
+
arr_opts = []
|
383
|
+
|
384
|
+
arr_opts << '--all' if options[:all]
|
385
|
+
arr_opts << '--force' if options[:force]
|
386
|
+
|
387
|
+
arr_opts << '--'
|
388
|
+
|
389
|
+
arr_opts << paths
|
390
|
+
|
391
|
+
arr_opts.flatten!
|
392
|
+
|
402
393
|
command('add', arr_opts)
|
403
394
|
end
|
404
395
|
|
@@ -416,10 +407,13 @@ module Git
|
|
416
407
|
end
|
417
408
|
|
418
409
|
def commit(message, opts = {})
|
419
|
-
arr_opts = [
|
420
|
-
arr_opts <<
|
410
|
+
arr_opts = []
|
411
|
+
arr_opts << "--message=#{message}" if message
|
412
|
+
arr_opts << '--amend' << '--no-edit' if opts[:amend]
|
413
|
+
arr_opts << '--all' if opts[:add_all] || opts[:all]
|
421
414
|
arr_opts << '--allow-empty' if opts[:allow_empty]
|
422
|
-
arr_opts << "--author
|
415
|
+
arr_opts << "--author=#{opts[:author]}" if opts[:author]
|
416
|
+
|
423
417
|
command('commit', arr_opts)
|
424
418
|
end
|
425
419
|
|
@@ -429,7 +423,26 @@ module Git
|
|
429
423
|
arr_opts << commit if commit
|
430
424
|
command('reset', arr_opts)
|
431
425
|
end
|
426
|
+
|
427
|
+
def clean(opts = {})
|
428
|
+
arr_opts = []
|
429
|
+
arr_opts << '--force' if opts[:force]
|
430
|
+
arr_opts << '-d' if opts[:d]
|
431
|
+
|
432
|
+
command('clean', arr_opts)
|
433
|
+
end
|
432
434
|
|
435
|
+
def revert(commitish, opts = {})
|
436
|
+
# Forcing --no-edit as default since it's not an interactive session.
|
437
|
+
opts = {:no_edit => true}.merge(opts)
|
438
|
+
|
439
|
+
arr_opts = []
|
440
|
+
arr_opts << '--no-edit' if opts[:no_edit]
|
441
|
+
arr_opts << commitish
|
442
|
+
|
443
|
+
command('revert', arr_opts)
|
444
|
+
end
|
445
|
+
|
433
446
|
def apply(patch_file)
|
434
447
|
arr_opts = []
|
435
448
|
arr_opts << '--' << patch_file if patch_file
|
@@ -527,7 +540,8 @@ module Git
|
|
527
540
|
|
528
541
|
def remote_add(name, url, opts = {})
|
529
542
|
arr_opts = ['add']
|
530
|
-
arr_opts << '-f' if opts[:with_fetch]
|
543
|
+
arr_opts << '-f' if opts[:with_fetch] || opts[:fetch]
|
544
|
+
arr_opts << '-t' << opts[:track] if opts[:track]
|
531
545
|
arr_opts << '--'
|
532
546
|
arr_opts << name
|
533
547
|
arr_opts << url
|
@@ -535,10 +549,8 @@ module Git
|
|
535
549
|
command('remote', arr_opts)
|
536
550
|
end
|
537
551
|
|
538
|
-
# this is documented as such, but seems broken for some reason
|
539
|
-
# i'll try to get around it some other way later
|
540
552
|
def remote_remove(name)
|
541
|
-
command('remote', ['rm',
|
553
|
+
command('remote', ['rm', name])
|
542
554
|
end
|
543
555
|
|
544
556
|
def remotes
|
@@ -562,7 +574,11 @@ module Git
|
|
562
574
|
command('push', [remote, branch])
|
563
575
|
command('push', ['--tags', remote]) if tags
|
564
576
|
end
|
565
|
-
|
577
|
+
|
578
|
+
def pull(remote='origin', branch='master')
|
579
|
+
command('pull', [remote, branch])
|
580
|
+
end
|
581
|
+
|
566
582
|
def tag_sha(tag_name)
|
567
583
|
head = File.join(@git_dir, 'refs', 'tags', tag_name)
|
568
584
|
return File.read(head).chomp if File.exists?(head)
|
@@ -674,11 +690,13 @@ module Git
|
|
674
690
|
|
675
691
|
def command(cmd, opts = [], chdir = true, redirect = '', &block)
|
676
692
|
ENV['GIT_DIR'] = @git_dir
|
677
|
-
ENV['GIT_INDEX_FILE'] = @git_index_file
|
678
693
|
ENV['GIT_WORK_TREE'] = @git_work_dir
|
694
|
+
ENV['GIT_INDEX_FILE'] = @git_index_file
|
695
|
+
|
679
696
|
path = @git_work_dir || @git_dir || @path
|
680
697
|
|
681
698
|
opts = [opts].flatten.map {|s| escape(s) }.join(' ')
|
699
|
+
|
682
700
|
git_cmd = "git #{cmd} #{opts} #{redirect} 2>&1"
|
683
701
|
|
684
702
|
out = nil
|
@@ -701,6 +719,60 @@ module Git
|
|
701
719
|
end
|
702
720
|
out
|
703
721
|
end
|
722
|
+
|
723
|
+
# Takes the diff command line output (as Array) and parse it into a Hash
|
724
|
+
#
|
725
|
+
# @param [String] diff_command the diff commadn to be used
|
726
|
+
# @param [Array] opts the diff options to be used
|
727
|
+
# @return [Hash] the diff as Hash
|
728
|
+
def diff_as_hash(diff_command, opts=[])
|
729
|
+
command_lines(diff_command, opts).inject({}) do |memo, line|
|
730
|
+
info, file = line.split("\t")
|
731
|
+
mode_src, mode_dest, sha_src, sha_dest, type = info.split
|
732
|
+
|
733
|
+
memo[file] = {
|
734
|
+
:mode_index => mode_dest,
|
735
|
+
:mode_repo => mode_src.to_s[1, 7],
|
736
|
+
:path => file,
|
737
|
+
:sha_repo => sha_src,
|
738
|
+
:sha_index => sha_dest,
|
739
|
+
:type => type
|
740
|
+
}
|
741
|
+
|
742
|
+
memo
|
743
|
+
end
|
744
|
+
end
|
745
|
+
|
746
|
+
# Returns an array holding the common options for the log commands
|
747
|
+
#
|
748
|
+
# @param [Hash] opts the given options
|
749
|
+
# @return [Array] the set of common options that the log command will use
|
750
|
+
def log_common_options(opts)
|
751
|
+
arr_opts = []
|
752
|
+
|
753
|
+
arr_opts << "-#{opts[:count]}" if opts[:count]
|
754
|
+
arr_opts << "--no-color"
|
755
|
+
arr_opts << "--since=#{opts[:since]}" if opts[:since].is_a? String
|
756
|
+
arr_opts << "--until=#{opts[:until]}" if opts[:until].is_a? String
|
757
|
+
arr_opts << "--grep=#{opts[:grep]}" if opts[:grep].is_a? String
|
758
|
+
arr_opts << "--author=#{opts[:author]}" if opts[:author].is_a? String
|
759
|
+
arr_opts << "#{opts[:between][0].to_s}..#{opts[:between][1].to_s}" if (opts[:between] && opts[:between].size == 2)
|
760
|
+
|
761
|
+
arr_opts
|
762
|
+
end
|
763
|
+
|
764
|
+
# Retrurns an array holding path options for the log commands
|
765
|
+
#
|
766
|
+
# @param [Hash] opts the given options
|
767
|
+
# @return [Array] the set of path options that the log command will use
|
768
|
+
def log_path_options(opts)
|
769
|
+
arr_opts = []
|
770
|
+
|
771
|
+
arr_opts << opts[:object] if opts[:object].is_a? String
|
772
|
+
arr_opts << '--' << opts[:path_limiter] if opts[:path_limiter]
|
773
|
+
|
774
|
+
arr_opts
|
775
|
+
end
|
704
776
|
|
705
777
|
def run_command(git_cmd, &block)
|
706
778
|
if block_given?
|