git.rb 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 52833f20baf0598073541425701ec14677832f98aa5a5f10d6b6fabb647c6b5e
4
+ data.tar.gz: f579c6fcc86ad91fdb91983ab08c0acb2bdfe33f7c160693406daeccfc6a9b62
5
+ SHA512:
6
+ metadata.gz: 8eec775af216cf3e2a1c3d87eb23763d74c7e7f2f6f29e764f5e70ba6880533ea7245f5d7722c980c082e24a4463eebf274d617af5ce62779b1ef940cf6d477d
7
+ data.tar.gz: 74ccdf65e4842e68b17f5f9f64cb8c79eda27d5b4b12753ea5cc4965041e72a6e4d608387f02f390b7ffe9a594b46d9753f5c383cdc4093c9afd5985373d96b9
@@ -0,0 +1,7 @@
1
+ # Array/all_but_first.rb
2
+ # Array#all_but_first
3
+
4
+ # 20180804
5
+ # 0.1.0 (The same version number as the current version of Thoran/Array/AllButFirst.)
6
+
7
+ require 'Thoran/Array/AllButFirst/all_but_first'
@@ -0,0 +1,7 @@
1
+ # Array/all_but_last.rb
2
+ # Array#all_but_last
3
+
4
+ # 20180804
5
+ # 0.1.0 (The same version number as the current version of Thoran/Array/AllButLast.)
6
+
7
+ require 'Thoran/Array/AllButLast/all_but_last'
@@ -0,0 +1,13 @@
1
+ # Git.rb
2
+ # Git
3
+
4
+ # 20200127, 0128, 0202, 0207, 0208
5
+ # 0.10.0
6
+
7
+ lib_dir = File.expand_path(File.join(__FILE__, '..'))
8
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
9
+
10
+ require 'Git/Blame'
11
+ require 'Git/Branch'
12
+ require 'Git/Log'
13
+ require 'Git/Remote'
@@ -0,0 +1,125 @@
1
+ # Git/Blame.rb
2
+ # Git::Blame
3
+
4
+ # Examples:
5
+ #
6
+ # require 'Git/Blame'
7
+ #
8
+ # git_blame = Git::Blame.new('file/in/git/repository.rb')
9
+ # => #<Git::Blame @filename='file/in/git/repository.rb'>
10
+ #
11
+ # git_blame.entries
12
+ # => [#<Git::PorcelainEntry @porcelain_output='...', @line_number=1>, ...]
13
+ #
14
+ # line_number = 123
15
+ # git_blame_porcelain_entry = git_blame.find(line_number)
16
+ # => #<Git::PorcelainEntry @porcelain_output='...', @line_number=123>
17
+ #
18
+ # git_blame_porcelain_entry.commit_hash
19
+ # => "c9ab2bce79441f15d0a37e2af68017e7680b7e8d"
20
+ #
21
+ # git_blame_porcelain_entry.author
22
+ # => "thoran"
23
+
24
+ require 'Array/all_but_first'
25
+ require 'Array/all_but_last'
26
+
27
+ module Git
28
+ class Blame
29
+
30
+ class PorcelainEntry
31
+
32
+ class << self
33
+
34
+ def parse(porcelain_output)
35
+ new(porcelain_output).parse
36
+ end
37
+
38
+ end # class << self
39
+
40
+ attr_reader :line_number
41
+
42
+ def initialize(porcelain_output, line_number = nil)
43
+ @porcelain_output = porcelain_output
44
+ @line_number = line_number
45
+ end
46
+
47
+ def parse
48
+ lines_with_keys.each do |line|
49
+ variable_name = line.split.first.tr('-','_')
50
+ value = line.split.all_but_first.join(' ')
51
+ instance_variable_set("@#{variable_name}", value)
52
+ self.class.class_eval("attr_reader :#{variable_name}")
53
+ end
54
+ self
55
+ end
56
+
57
+ def commit_hash
58
+ lines.first.split.first
59
+ end
60
+
61
+ def previous_commit_hash
62
+ @previous.split.first
63
+ end
64
+
65
+ def code
66
+ lines.last
67
+ end
68
+
69
+ private
70
+
71
+ def lines
72
+ @lines ||= @porcelain_output.split("\n")
73
+ end
74
+
75
+ def lines_with_keys
76
+ @lines_with_keys ||= lines.all_but_first.all_but_last
77
+ end
78
+
79
+ end # class PorcelainEntry
80
+
81
+ def initialize(filename, line_number = nil)
82
+ @filename = filename
83
+ @line_number = line_number
84
+ end
85
+
86
+ def command_string
87
+ if @line_number
88
+ "git --no-pager blame -L #{@line_number},#{@line_number} #{@filename} --line-porcelain"
89
+ else
90
+ "git --no-pager blame #{@filename} --line-porcelain"
91
+ end
92
+ end
93
+
94
+ def blame_output
95
+ `#{command_string}`
96
+ end
97
+
98
+ def entries
99
+ line_count = 0
100
+ porcelain_entry_string = ''
101
+ entries = []
102
+ blame_array = blame_output.split("\n")
103
+ line_number = 0
104
+ i = -1
105
+ until i >= blame_array.size - 1
106
+ until blame_array[i].split.first == 'filename'
107
+ porcelain_entry_string << blame_array[i += 1]
108
+ porcelain_entry_string << "\n"
109
+ end
110
+ porcelain_entry_string << blame_array[i += 1]
111
+ porcelain_entry_string << "\n"
112
+ entries << PorcelainEntry.new(porcelain_entry_string, line_number += 1).parse
113
+ line_count = 0
114
+ porcelain_entry_string = ''
115
+ end
116
+ entries
117
+ end
118
+
119
+ def find(line_number)
120
+ @line_number = line_number
121
+ entries.detect{|entry| entry.line_number == @line_number}
122
+ end
123
+
124
+ end
125
+ end
@@ -0,0 +1,130 @@
1
+ # Git/Branch.rb
2
+ # Git::Branch
3
+
4
+ # Examples:
5
+ #
6
+ # require 'Git/Branch'
7
+ #
8
+ # Git::Branch.local
9
+ # => Git::Branch
10
+ #
11
+ # Git::Branch.local.all, Git::Branch.all
12
+ # => [#<Git::Branch @name="master">, ...]
13
+ #
14
+ # Git::Branch.remote.all
15
+ # => [#<Git::Branch @name="master">, ...]
16
+ #
17
+ # Git::Branch.merged.all
18
+ # => [#<Git::Branch @name="master">, ...]
19
+ #
20
+ # Git::Branch.remote.merged.all
21
+ # => [#<Git::Branch @name="master">, ...]
22
+ #
23
+ # Git::Branch.current
24
+ # => #<Git::Branch @name="master">
25
+ #
26
+ # Git::Branch.current.master?
27
+ # => true
28
+ #
29
+ # git_branch = Git::Branch.new('branch_name')
30
+ # => #<Git::Branch @name="branch_name">
31
+ #
32
+ # git_branch.merged?
33
+ # => true/false
34
+ #
35
+ # git_branch.name, git_branch.to_s
36
+ # => "branch_name"
37
+ #
38
+ # git_branch = Git::Branch.new('branch_name', remote: 'remote_name')
39
+ # => #<Git::Branch @name="branch_name" @remote="remote_name">
40
+ #
41
+ # git_branch.remote
42
+ # => "remote_name"
43
+
44
+ require 'Array/all_but_first'
45
+
46
+ module Git
47
+ class Branch
48
+
49
+ @switches = []
50
+
51
+ class << self
52
+
53
+ def local
54
+ self
55
+ end
56
+
57
+ def remote
58
+ @switches << '--remote'
59
+ self
60
+ end
61
+
62
+ def merged
63
+ @switches << '--merged'
64
+ self
65
+ end
66
+
67
+ def command_string
68
+ command_string = ['git branch', @switches.join(' ')].join(' ').strip
69
+ @switches = []
70
+ command_string
71
+ end
72
+
73
+ def branch_output
74
+ `#{command_string}`
75
+ end
76
+
77
+ def all
78
+ result = branch_output.split("\n").collect do |branch|
79
+ if @switches.include?('--remote')
80
+ branch_parts = branch.split('/')
81
+ remote, branch_name = branch_parts.first.sub('*', '').strip, branch_parts.all_but_first.join('/')
82
+ new(branch_name, remote: remote)
83
+ else
84
+ branch_name = branch.sub('*', '').strip
85
+ new(branch_name)
86
+ end
87
+ end
88
+ result
89
+ end
90
+
91
+ def current
92
+ branch_name = branch_output.split("\n").detect{|branch| branch =~ /\*/}.sub('*', '').strip
93
+ new(branch_name)
94
+ end
95
+ alias_method :head, :current
96
+
97
+ end # class << self
98
+
99
+ attr_accessor :name
100
+ attr_accessor :remote
101
+
102
+ def initialize(name = nil, **args)
103
+ @name = name
104
+ @remote = args[:remote]
105
+ end
106
+
107
+ def merged?
108
+ if @remote
109
+ self.class.remote.merged.all.collect{|branch| branch.name}.include?(@remote + '/' + @name)
110
+ else
111
+ self.class.merged.all.collect{|branch| branch.name}.include?(@name)
112
+ end
113
+ end
114
+
115
+ def to_s
116
+ if @remote
117
+ @remote + '/' + @name
118
+ else
119
+ @name
120
+ end
121
+ end
122
+
123
+ def method_missing(method_name, *args, &block)
124
+ if method_name.to_s =~ /\?$/ && !self.class.instance_methods.include?(method_name)
125
+ @name == method_name.to_s.sub('?', '')
126
+ end
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,93 @@
1
+ # Git/Log.rb
2
+ # Git::Log
3
+
4
+ # Examples:
5
+ #
6
+ # require 'Git/Log'
7
+ #
8
+ # git_log = Git::Log.parse(`git log`)
9
+ # => [#<Git::Log @commits = [#<Git::Log::Commit @hash=..., @author="thoran", @date=..., @message=...>, ...]>
10
+ #
11
+ # git_log.commits
12
+ # => [#<Git::Log::Commit @hash=..., @author="thoran", @date=..., @message=...>, ...]
13
+ #
14
+ # git_log.commits.first
15
+ # => #<Git::Log::Commit @hash=..., @author="thoran", @date=..., @message=...>
16
+ #
17
+ # git_log.commits.first.author
18
+ # => "thoran"
19
+
20
+ require 'Ordinal/Array'
21
+
22
+ module Git
23
+ class Log
24
+
25
+ class Commit
26
+
27
+ class << self
28
+ def parse(commit_string)
29
+ parsed_commit_string = commit_string.split("\n").collect{|line| line.strip}.select{|line| !line.empty?}
30
+ Commit.new(
31
+ hash: parsed_commit_string.first.gsub(/^commit /, ''),
32
+ author: parsed_commit_string.second.gsub(/^Author: /, ''),
33
+ date: parsed_commit_string.third.gsub(/^Date: /, ''),
34
+ message: parsed_commit_string.fourth
35
+ )
36
+ end
37
+ end # class << self
38
+
39
+ attr_reader :hash
40
+ attr_reader :author
41
+ attr_reader :date
42
+ attr_reader :message
43
+
44
+ def initialize(values = {})
45
+ @hash = values[:hash]
46
+ @author = values[:author]
47
+ @date = values[:date]
48
+ @message = values[:message]
49
+ end
50
+
51
+ end # class Commit
52
+
53
+ @commits = []
54
+
55
+ class << self
56
+
57
+ attr_reader :commits
58
+
59
+ def parse(log_stream)
60
+ commit_log = Log.new
61
+ commit_string = ''
62
+ log_stream.each_line do |line|
63
+ line.lstrip!
64
+ if line =~ /^commit/ && !commit_string.empty?
65
+ commit_log.prepend(Commit.parse(commit_string))
66
+ commit_string = line
67
+ else
68
+ commit_string << line
69
+ end
70
+ end
71
+ commit_log.prepend(Commit.parse(commit_string))
72
+ commit_log
73
+ end
74
+
75
+ end # class << self
76
+
77
+ attr_reader :commits
78
+
79
+ def initialize(commits = [])
80
+ @commits = commits
81
+ end
82
+
83
+ def prepend(commit_object)
84
+ commits.unshift(commit_object)
85
+ end
86
+ alias_method :unshift, :prepend
87
+
88
+ def method_missing(method_name, *args, &block)
89
+ commits.send(method_name, *args, &block)
90
+ end
91
+
92
+ end
93
+ end
@@ -0,0 +1,87 @@
1
+ # Git/Remote.rb
2
+ # Git::Remote
3
+
4
+ # Examples:
5
+ #
6
+ # require 'Git/Remote'
7
+ #
8
+ # Git::Remote.all
9
+ # => [#<Git::Remote @name='origin', @url='git@github.com:thoran/rails.git'>, #<Git::Remote @name='upstream', @url='git@github.com:rails/rails.git'>]
10
+ #
11
+ # Git::Remote.exist?('origin')
12
+ # => true
13
+ #
14
+ # git_remote = Git::Remote.find('origin')
15
+ # => #<Git::Remote @name="origin" @url="git@github.com:thoran/rails.git">
16
+ #
17
+ # git_remote.to_s
18
+ # => "origin git@github.com:thoran/rails.git"
19
+ #
20
+ # git_remote.name
21
+ # => "origin"
22
+
23
+ module Git
24
+ class Remote
25
+
26
+ class << self
27
+
28
+ def parse_line(remote_output_line)
29
+ name, url = remote_output_line.split
30
+ new(name: name, url: url)
31
+ end
32
+
33
+ def remote_output
34
+ `git remote --verbose`
35
+ end
36
+
37
+ def all
38
+ remote_output.split("\n").collect do |remote|
39
+ parse_line(remote)
40
+ end.uniq{|remote| remote.name}
41
+ end
42
+
43
+ def find(remote_name)
44
+ all.detect{|remote| remote.name == remote_name}
45
+ end
46
+
47
+ def add_command(remote_name, remote_url)
48
+ ['git remote add', remote_name, remote_url].join(' ')
49
+ end
50
+
51
+ def add(remote_name, remote_url)
52
+ system add_command(remote_name, remote_url)
53
+ end
54
+
55
+ def remove_command(remote_name)
56
+ ['git remote remove', remote_name].join(' ')
57
+ end
58
+
59
+ def remove(remote_name, remote_url)
60
+ system remove_command(remote_name)
61
+ end
62
+
63
+ def exist?(remote_name)
64
+ !!find(remote_name)
65
+ end
66
+
67
+ end # class << self
68
+
69
+ attr_accessor :name
70
+ attr_accessor :url
71
+
72
+ def initialize(name:, url:)
73
+ @name = name
74
+ @url = url
75
+ end
76
+
77
+ def remove
78
+ self.class.remove(@name, @url)
79
+ end
80
+ alias_method :delete, :remove
81
+
82
+ def to_s
83
+ "#{@name} #{@url}"
84
+ end
85
+
86
+ end
87
+ end
@@ -0,0 +1,3 @@
1
+ module Git
2
+ VERSION = '0.10.0'
3
+ end
@@ -0,0 +1,155 @@
1
+ # Ordinal.rb
2
+ # Ordinal
3
+
4
+ # 20140316
5
+ # 0.2.0
6
+
7
+ # Description: This is a collection of methods which relies upon an object having an entries method.
8
+
9
+ # Notes:
10
+ # 1. This was originally meant to be extensions on Enumerable, as can be seen in version 0.0.0, but I decided that any object which provides for an ordered list of entries by way of having an entries method should be able to make use of this.
11
+
12
+ # Changes since 0.1:
13
+ # 1. - require 'File/self.relative_path' from Ordinal/Array and replaced with require_relative.
14
+ # 2. - require 'File/self.relative_path' from Ordinal/Array and replaced with require_relative.
15
+
16
+ module Ordinal
17
+
18
+ def first
19
+ entries[0]
20
+ end
21
+
22
+ def second
23
+ entries[1]
24
+ end
25
+
26
+ def third
27
+ entries[2]
28
+ end
29
+
30
+ def fourth
31
+ entries[3]
32
+ end
33
+
34
+ def fifth
35
+ entries[4]
36
+ end
37
+
38
+ def sixth
39
+ entries[5]
40
+ end
41
+
42
+ def seventh
43
+ entries[6]
44
+ end
45
+
46
+ def eighth
47
+ entries[7]
48
+ end
49
+
50
+ def ninth
51
+ entries[8]
52
+ end
53
+
54
+ def tenth
55
+ entries[9]
56
+ end
57
+
58
+ def eleventh
59
+ entries[10]
60
+ end
61
+
62
+ def twelfth
63
+ entries[11]
64
+ end
65
+
66
+ def thirteenth
67
+ entries[12]
68
+ end
69
+
70
+ def fourteenth
71
+ entries[13]
72
+ end
73
+
74
+ def fifteenth
75
+ entries[14]
76
+ end
77
+
78
+ def sixteenth
79
+ entries[15]
80
+ end
81
+
82
+ def seventeenth
83
+ entries[16]
84
+ end
85
+
86
+ def eighteenth
87
+ entries[17]
88
+ end
89
+
90
+ def ninteenth
91
+ entries[18]
92
+ end
93
+
94
+ def twentieth
95
+ entries[19]
96
+ end
97
+
98
+ def tenth_last
99
+ entries[count - 10]
100
+ end
101
+
102
+ def ninth_last
103
+ entries[count - 9]
104
+ end
105
+
106
+ def eighth_last
107
+ entries[count - 8]
108
+ end
109
+
110
+ def seventh_last
111
+ entries[count - 7]
112
+ end
113
+
114
+ def sixth_last
115
+ entries[count - 6]
116
+ end
117
+
118
+ def fifth_last
119
+ entries[count - 5]
120
+ end
121
+
122
+ def fourth_last
123
+ entries[count - 4]
124
+ end
125
+
126
+ def third_last
127
+ entries[count - 3]
128
+ end
129
+
130
+ def second_last
131
+ entries[count - 2]
132
+ end
133
+
134
+ def last
135
+ entries[count - 1]
136
+ end
137
+ alias_method :first_last, :last
138
+
139
+ def all_but_first
140
+ entries.drop(1)
141
+ end
142
+
143
+ def all_but_last
144
+ entries.take(count - 1)
145
+ end
146
+
147
+ def all_but_first_and_last
148
+ entries.all_but_first.all_but_last
149
+ end
150
+
151
+ def first_and_last
152
+ [entries.first] + [entries.last]
153
+ end
154
+
155
+ end
@@ -0,0 +1,8 @@
1
+ # Ordinal/Array.rb
2
+ # Ordinal/Array
3
+
4
+ require_relative '../Ordinal'
5
+
6
+ class Array
7
+ include Ordinal
8
+ end
@@ -0,0 +1,28 @@
1
+ # Thoran/Array/AllButFirst/all_but_first.rb
2
+ # Thoran::Array::AllButFirst#all_but_first
3
+
4
+ # 20141223
5
+ # 0.1.0
6
+
7
+ # Description: This returns a copy of the receiving array with the first element removed.
8
+
9
+ # Changes:
10
+ # 1. + Thoran namespace.
11
+
12
+ require 'Thoran/Array/FirstX/firstX'
13
+
14
+ module Thoran
15
+ module Array
16
+ module AllButFirst
17
+
18
+ def all_but_first
19
+ d = self.dup
20
+ d.first!
21
+ d
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+
28
+ Array.send(:include, Thoran::Array::AllButFirst)
@@ -0,0 +1,28 @@
1
+ # Thoran/Array/AllButLast/all_but_last.rb
2
+ # Thoran::Array::AllButLast#all_but_last
3
+
4
+ # 20180804
5
+ # 0.1.0
6
+
7
+ # Description: This returns a copy of the receiving array with the last element removed.
8
+
9
+ # Changes:
10
+ # 1. + Thoran namespace.
11
+
12
+ require 'Thoran/Array/LastX/lastX'
13
+
14
+ module Thoran
15
+ module Array
16
+ module AllButLast
17
+
18
+ def all_but_last
19
+ d = self.dup
20
+ d.last!
21
+ d
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+
28
+ Array.send(:include, Thoran::Array::AllButLast)
@@ -0,0 +1,32 @@
1
+ # Thoran/Array/FirstX/firstX.rb
2
+ # Thoran::Array::FirstX#first!
3
+
4
+ # 20180804
5
+ # 0.3.3
6
+
7
+ # Description: Sometimes it makes more sense to treat arrays this way.
8
+
9
+ # Changes since 0.2:
10
+ # 1. Added the original version 0.1.0 of the implementation to the later 0.1.0!
11
+ # 0/1
12
+ # 2. Switched the tests to spec-style.
13
+ # 1/2
14
+ # 3. Added a test for the state of the array afterward, since this is meant to be an in place change.
15
+ # 2/3
16
+ # 4. Added tests for the extended functionality introduced in the first version 0.1.0.
17
+
18
+ module Thoran
19
+ module Array
20
+ module FirstX
21
+
22
+ def first!(n = 1)
23
+ return_value = []
24
+ n.times{return_value << self.shift}
25
+ return_value.size == 1 ? return_value[0] : return_value
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+
32
+ Array.send(:include, Thoran::Array::FirstX)
@@ -0,0 +1,33 @@
1
+ # Thoran/Array/LastX/lastX.rb
2
+ # Thoran::Array::LastX#last!
3
+
4
+ # 20180804
5
+ # 0.2.3
6
+
7
+ # Description: Sometimes it makes more sense to treat arrays this way.
8
+
9
+ # Changes since 0.1:
10
+ # 1. Added the complement of the extended version of Array#first!.
11
+ # 0/1
12
+ # 2. Switched the tests to spec-style.
13
+ # 1/2
14
+ # 3. Added a test for the state of the array afterward, since this is meant to be an in place change.
15
+ # 2/3
16
+ # 4. Added tests for the extended functionality introduced in the first version 0.1.0.
17
+ # 5. Fixed the implementation, so that the order is retained by unshifting the popped values rather than appending the shifted values as is the case with Array#first!.
18
+
19
+ module Thoran
20
+ module Array
21
+ module LastX
22
+
23
+ def last!(n = 1)
24
+ return_value = []
25
+ n.times{return_value.unshift(self.pop)}
26
+ return_value.size == 1 ? return_value[0] : return_value
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+
33
+ Array.send(:include, Thoran::Array::LastX)
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git.rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.10.0
5
+ platform: ruby
6
+ authors:
7
+ - thoran
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-08 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Do stuff with git-blame, git-branch, git-log, and git-remote from Ruby.
14
+ email: code@thoran.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/Array/all_but_first.rb
20
+ - lib/Array/all_but_last.rb
21
+ - lib/Git.rb
22
+ - lib/Git/Blame.rb
23
+ - lib/Git/Branch.rb
24
+ - lib/Git/Log.rb
25
+ - lib/Git/Remote.rb
26
+ - lib/Git/VERSION.rb
27
+ - lib/Ordinal.rb
28
+ - lib/Ordinal/Array.rb
29
+ - lib/Thoran/AllButFirst/all_but_first.rb
30
+ - lib/Thoran/AllButLast/all_but_last.rb
31
+ - lib/Thoran/FirstX/firstX.rb
32
+ - lib/Thoran/LastX/lastX.rb
33
+ homepage: http://github.com/thoran/git.rb
34
+ licenses:
35
+ - MIT
36
+ metadata: {}
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: 1.9.3
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubygems_version: 3.1.2
53
+ signing_key:
54
+ specification_version: 4
55
+ summary: Do git stuff from Ruby.
56
+ test_files: []