git-process 0.9.1.pre3 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/CHANGELOG.md +0 -0
  2. data/Gemfile +2 -2
  3. data/Gemfile.lock +2 -0
  4. data/README.md +27 -9
  5. data/bin/git-new-fb +42 -13
  6. data/bin/git-pull-request +79 -13
  7. data/bin/git-sync +47 -13
  8. data/bin/git-to-master +56 -13
  9. data/git-process.gemspec +1 -1
  10. data/lib/git-process/{abstract-error-builder.rb → abstract_error_builder.rb} +13 -3
  11. data/lib/git-process/{git-abstract-merge-error-builder.rb → git_abstract_merge_error_builder.rb} +15 -5
  12. data/lib/git-process/{git-branch.rb → git_branch.rb} +13 -1
  13. data/lib/git-process/git_branches.rb +72 -0
  14. data/lib/git-process/{git-lib.rb → git_lib.rb} +82 -70
  15. data/lib/git-process/git_merge_error.rb +38 -0
  16. data/lib/git-process/git_process.rb +124 -0
  17. data/lib/git-process/git_process_error.rb +18 -0
  18. data/lib/git-process/git_process_options.rb +101 -0
  19. data/lib/git-process/git_rebase_error.rb +38 -0
  20. data/lib/git-process/{git-status.rb → git_status.rb} +13 -1
  21. data/lib/git-process/{github-client.rb → github_client.rb} +13 -1
  22. data/lib/git-process/github_pull_request.rb +107 -0
  23. data/lib/git-process/{github-service.rb → github_service.rb} +39 -21
  24. data/lib/git-process/new_fb.rb +40 -0
  25. data/lib/git-process/parked_changes_error.rb +40 -0
  26. data/lib/git-process/pull_request.rb +61 -0
  27. data/lib/git-process/rebase_to_master.rb +110 -0
  28. data/lib/git-process/sync.rb +63 -0
  29. data/lib/git-process/uncommitted_changes_error.rb +23 -0
  30. data/lib/git-process/version.rb +19 -9
  31. data/spec/GitRepoHelper.rb +35 -21
  32. data/spec/{git-abstract-merge-error-builder_spec.rb → git_abstract_merge_error_builder_spec.rb} +3 -3
  33. data/spec/{git-lib_spec.rb → git_lib_spec.rb} +79 -16
  34. data/spec/git_process_spec.rb +36 -0
  35. data/spec/{git-status_spec.rb → git_status_spec.rb} +28 -29
  36. data/spec/github_pull_request_spec.rb +91 -0
  37. data/spec/{github-service_spec.rb → github_service_spec.rb} +1 -1
  38. data/spec/new_fb_spec.rb +80 -0
  39. data/spec/rebase_to_master_spec.rb +314 -0
  40. data/spec/spec_helper.rb +1 -1
  41. data/spec/sync_spec.rb +149 -0
  42. metadata +46 -43
  43. data/lib/git-process/git-branches.rb +0 -53
  44. data/lib/git-process/git-merge-error.rb +0 -31
  45. data/lib/git-process/git-new-fb-options.rb +0 -34
  46. data/lib/git-process/git-process-error.rb +0 -10
  47. data/lib/git-process/git-process-options.rb +0 -82
  48. data/lib/git-process/git-process.rb +0 -194
  49. data/lib/git-process/git-pull-request-options.rb +0 -42
  50. data/lib/git-process/git-rebase-error.rb +0 -31
  51. data/lib/git-process/git-sync-options.rb +0 -34
  52. data/lib/git-process/git-to-master-options.rb +0 -18
  53. data/lib/git-process/parked-changes-error.rb +0 -32
  54. data/lib/git-process/pull-request.rb +0 -38
  55. data/lib/git-process/uncommitted-changes-error.rb +0 -15
  56. data/spec/git-process_spec.rb +0 -328
  57. data/spec/pull-request_spec.rb +0 -57
@@ -1,10 +1,20 @@
1
- require "rubygems"
2
- require "bundler/setup"
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
3
12
 
4
13
  require 'logger'
5
- require 'git-branch'
6
- require 'git-branches'
7
- require 'git-status'
14
+ require 'git-process/git_branch'
15
+ require 'git-process/git_branches'
16
+ require 'git-process/git_status'
17
+ require 'git-process/git_process_error'
8
18
 
9
19
 
10
20
  class String
@@ -18,67 +28,51 @@ class String
18
28
  end
19
29
 
20
30
 
21
- module Git
31
+ module GitProc
22
32
 
23
33
  class GitExecuteError < StandardError
24
34
  end
25
35
 
26
36
 
27
- # @!attribute [r] logger
28
- # @return [Logger] a logger
29
- # @!attribute [r] git
30
- # @return [Git] an instance of the Git library
31
- class GitLib
32
- attr_reader :logger
37
+ #
38
+ # Provides Git commands
39
+ #
40
+ # = Assumes =
41
+ # log_level
42
+ # workdir
43
+ #
44
+ module GitLib
33
45
 
34
- def initialize(dir, options = {})
35
- initialize_logger(options[:logger], options[:log_level])
36
- initialize_git(dir)
37
- end
38
-
39
-
40
- def initialize_logger(logger, log_level)
41
- if logger
42
- @logger = logger
43
- else
46
+ def logger
47
+ unless @logger
44
48
  @logger = Logger.new(STDOUT)
45
49
  @logger.level = log_level || Logger::WARN
46
50
  @logger.datetime_format = "%Y-%m-%d %H:%M:%S"
47
51
  f = Logger::Formatter.new
48
52
  @logger.formatter = proc do |severity, datetime, progname, msg|
49
53
  "#{msg}\n"
50
- # "#{severity[0..0]}: #{datetime.strftime(@logger.datetime_format)}: #{msg}\n"
51
54
  end
52
55
  end
56
+ @logger
53
57
  end
54
58
 
55
59
 
56
- def initialize_git(dir, git = nil)
57
- if dir
58
- @workdir = File.expand_path(dir)
59
- unless File.directory?(File.join(workdir, '.git'))
60
- logger.info { "Initializing new repository at #{workdir}" }
61
- command(:init)
62
- else
63
- logger.debug { "Opening existing repository at #{workdir}" }
64
- end
65
- end
60
+ def server_name
61
+ @server_name ||= remote_name
66
62
  end
67
63
 
68
64
 
69
- private :initialize_logger, :initialize_git
70
-
71
-
72
- def workdir
73
- @workdir
65
+ def master_branch
66
+ @master_branch ||= config('gitProcess.integrationBranch') || 'master'
74
67
  end
75
68
 
76
69
 
70
+ # @return [Boolean] does this have a remote defined?
77
71
  def has_a_remote?
78
- if @remote == nil
79
- @remote = (command('remote') != '')
72
+ if @has_remote == nil
73
+ @has_remote = (command(:remote) != '')
80
74
  end
81
- @remote
75
+ @has_remote
82
76
  end
83
77
 
84
78
 
@@ -102,13 +96,13 @@ module Git
102
96
  end
103
97
 
104
98
 
105
- def fetch
106
- command(:fetch, ['-p', Process.server_name])
99
+ def fetch(name = remote_name)
100
+ command(:fetch, ['-p', name])
107
101
  end
108
102
 
109
103
 
110
104
  def branches
111
- GitBranches.new(self)
105
+ GitProc::GitBranches.new(self)
112
106
  end
113
107
 
114
108
 
@@ -129,7 +123,7 @@ module Git
129
123
  def branch(branch_name, opts = {})
130
124
  args = []
131
125
  if opts[:delete]
132
- logger.info { "Deleting local branch '#{branch_name}'."}
126
+ logger.info { "Deleting local branch '#{branch_name}'."} unless branch_name == '_parking_'
133
127
 
134
128
  args << (opts[:force] ? '-D' : '-d')
135
129
  args << branch_name
@@ -177,14 +171,22 @@ module Git
177
171
 
178
172
  if opts[:delete]
179
173
  if remote_branch
180
- opts[:delete] = remote_branch
174
+ rb = remote_branch
181
175
  elsif local_branch
182
- opts[:delete] = local_branch
176
+ rb = local_branch
177
+ elsif !(opts[:delete].is_a? TrueClass)
178
+ rb = opts[:delete]
183
179
  else
184
- raise ArgumentError.new("Need a branch name to delete.") if opts[:delete].is_a? TrueClass
180
+ raise ArgumentError.new("Need a branch name to delete.")
185
181
  end
186
- logger.info { "Deleting remote branch '#{opts[:delete]}' on '#{remote_name}'."}
187
- args << '--delete' << opts[:delete]
182
+
183
+ int_branch = master_branch
184
+ if rb == int_branch
185
+ raise GitProc::GitProcessError.new("Can not delete the integration branch '#{int_branch}'")
186
+ end
187
+
188
+ logger.info { "Deleting remote branch '#{rb}' on '#{remote_name}'."}
189
+ args << '--delete' << rb
188
190
  else
189
191
  local_branch ||= branches.current
190
192
  remote_branch ||= local_branch
@@ -239,7 +241,7 @@ module Git
239
241
  args = []
240
242
  args << '-f' if opts[:force]
241
243
  args << file
242
- command('rm', args)
244
+ command(:rm, args)
243
245
  end
244
246
 
245
247
 
@@ -248,21 +250,24 @@ module Git
248
250
  end
249
251
 
250
252
 
251
- def config(key = nil, value = nil)
253
+ def config(key = nil, value = nil, global = false)
252
254
  if key and value
253
- command('config', [key, value])
254
- config_hash[key] = value
255
+ args = global ? ['--global'] : []
256
+ args << key << value
257
+ command(:config, args)
258
+ config_hash[key] = value unless config_hash.empty?
255
259
  value
256
260
  elsif key
257
261
  value = config_hash[key]
258
262
  unless value
259
- value = command('config', ['--get', key])
260
- config_hash[key] = value
263
+ value = command(:config, ['--get', key])
264
+ value = nil if value.empty?
265
+ config_hash[key] = value unless config_hash.empty?
261
266
  end
262
267
  value
263
268
  else
264
269
  if config_hash.empty?
265
- str = command('config', '--list')
270
+ str = command(:config, '--list')
266
271
  lines = str.split("\n")
267
272
  lines.each do |line|
268
273
  (key, *values) = line.split('=')
@@ -276,14 +281,27 @@ module Git
276
281
 
277
282
  def repo_name
278
283
  unless @repo_name
279
- origin_url = config['remote.origin.url']
280
- raise Git::Process::GitProcessError.new("There is not origin url set up.") if origin_url.empty?
284
+ origin_url = config("remote.#{remote_name}.url")
285
+ raise GitProc::Process::GitProcessError.new("There is no #{remote_name} url set up.") if origin_url.empty?
281
286
  @repo_name = origin_url.sub(/^.*:(.*?)(.git)?$/, '\1')
282
287
  end
283
288
  @repo_name
284
289
  end
285
290
 
286
291
 
292
+ def remote_name
293
+ unless @remote_name
294
+ remote_str = command(:remote)
295
+ unless remote_str == nil or remote_str.empty?
296
+ @remote_name = remote_str.split(/\n/)[0]
297
+ raise "!@remote_name.is_a? String" unless @remote_name.is_a? String
298
+ end
299
+ logger.debug {"Using remote name of '#{@remote_name}'"}
300
+ end
301
+ @remote_name
302
+ end
303
+
304
+
287
305
  #
288
306
  # Returns the status of the git repository.
289
307
  #
@@ -311,30 +329,24 @@ module Git
311
329
 
312
330
 
313
331
  def rerere_enabled?
314
- re = command('config', ['--get', 'rerere.enabled'])
332
+ re = config('rerere.enabled')
315
333
  re && re.to_boolean
316
334
  end
317
335
 
318
336
 
319
337
  def rerere_enabled(re, global = true)
320
- args = []
321
- args << '--global' if global
322
- args << 'rerere.enabled' << re
323
- command(:config, args)
338
+ config('rerere.enabled', re, global)
324
339
  end
325
340
 
326
341
 
327
342
  def rerere_autoupdate?
328
- re = command('config', ['--get', 'rerere.autoupdate'])
343
+ re = config('rerere.autoupdate')
329
344
  re && re.to_boolean
330
345
  end
331
346
 
332
347
 
333
348
  def rerere_autoupdate(re, global = true)
334
- args = []
335
- args << '--global' if global
336
- args << 'rerere.autoupdate' << re
337
- command(:config, args)
349
+ config('rerere.autoupdate', re, global)
338
350
  end
339
351
 
340
352
 
@@ -388,7 +400,7 @@ module Git
388
400
  if $?.exitstatus == 1 && out == ''
389
401
  return ''
390
402
  end
391
- raise Git::GitExecuteError.new(git_cmd + ':' + out.to_s)
403
+ raise GitProc::GitExecuteError.new(git_cmd + ':' + out.to_s)
392
404
  end
393
405
  out
394
406
  end
@@ -0,0 +1,38 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
13
+ require 'git-process/git_abstract_merge_error_builder'
14
+
15
+ module GitProc
16
+
17
+ class MergeError < GitProcessError
18
+ include AbstractMergeErrorBuilder
19
+
20
+ attr_reader :error_message, :lib
21
+
22
+ def initialize(merge_error_message, lib)
23
+ @lib = lib
24
+ @error_message = merge_error_message
25
+
26
+ msg = build_message
27
+
28
+ super(msg)
29
+ end
30
+
31
+
32
+ def continue_command
33
+ 'git commit'
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,124 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
13
+ require 'git-process/git_lib'
14
+ require 'git-process/git_rebase_error'
15
+ require 'git-process/git_merge_error'
16
+
17
+
18
+ module GitProc
19
+
20
+ class Process
21
+ include GitLib
22
+
23
+ def initialize(dir, opts = {})
24
+ @log_level = Process.log_level(opts)
25
+
26
+ if dir
27
+ @workdir = find_workdir(dir)
28
+ if @workdir.nil?
29
+ @workdir = dir
30
+ logger.info { "Initializing new repository at #{workdir}" }
31
+ command(:init)
32
+ else
33
+ logger.debug { "Opening existing repository at #{workdir}" }
34
+ end
35
+ end
36
+ end
37
+
38
+
39
+ def run
40
+ begin
41
+ runner
42
+ rescue GitProc::GitProcessError => exp
43
+ puts exp.message
44
+ exit(-1)
45
+ end
46
+ end
47
+
48
+
49
+ def runner
50
+ # extension point - does nothing by default
51
+ end
52
+
53
+
54
+ def workdir
55
+ @workdir
56
+ end
57
+
58
+
59
+ def log_level
60
+ @log_level
61
+ end
62
+
63
+
64
+ def log_level=(ll)
65
+ @log_level = ll
66
+ end
67
+
68
+
69
+ def remote_master_branch
70
+ "#{server_name}/#{master_branch}"
71
+ end
72
+
73
+
74
+ def Process.log_level(opts)
75
+ if opts[:quiet]
76
+ Logger::ERROR
77
+ elsif opts[:verbose]
78
+ Logger::DEBUG
79
+ else
80
+ Logger::INFO
81
+ end
82
+ end
83
+
84
+
85
+ def is_parked?
86
+ mybranches = branches
87
+ mybranches.parking == mybranches.current
88
+ end
89
+
90
+
91
+ private
92
+
93
+
94
+ def find_workdir(dir)
95
+ if dir == File::SEPARATOR
96
+ nil
97
+ elsif File.directory?(File.join(dir, '.git'))
98
+ dir
99
+ else
100
+ find_workdir(File.expand_path("#{dir}/.."))
101
+ end
102
+ end
103
+
104
+
105
+ def proc_rebase(base)
106
+ begin
107
+ rebase(base)
108
+ rescue GitExecuteError => rebase_error
109
+ raise RebaseError.new(rebase_error.message, self)
110
+ end
111
+ end
112
+
113
+
114
+ def proc_merge(base)
115
+ begin
116
+ merge(base)
117
+ rescue GitExecuteError => merge_error
118
+ raise MergeError.new(merge_error.message, self)
119
+ end
120
+ end
121
+
122
+ end
123
+
124
+ end
@@ -0,0 +1,18 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
13
+ module GitProc
14
+
15
+ class GitProcessError < RuntimeError
16
+ end
17
+
18
+ end
@@ -0,0 +1,101 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
13
+ require 'optparse'
14
+ require 'trollop'
15
+ require 'git-process/version'
16
+
17
+ module GitProc
18
+
19
+ module GitProcessOptions
20
+
21
+ DEBUG = false
22
+
23
+ def parse_cli(filename, argv)
24
+ parser = Trollop::Parser.new
25
+ parser.version "#{filename} #{GitProc::Version::STRING}"
26
+
27
+ parser.banner "#{summary}\n\n"
28
+ parser.banner "\nUsage:\n #{usage(filename)}\n\nWhere [options] are:"
29
+
30
+ extend_opts(parser)
31
+ standard_opts(parser)
32
+
33
+ parser.banner "\n#{description}"
34
+
35
+ opts = Trollop::with_standard_exception_handling parser do
36
+ raise Trollop::HelpNeeded if ARGV.empty? and !empty_argv_ok?
37
+ parser.parse argv
38
+ end
39
+
40
+ opts[:info] = false if opts[:verbose] || opts[:quiet]
41
+ opts[:info] = true if opts[:info_given]
42
+
43
+ post_parse(opts, argv)
44
+
45
+ if (DEBUG)
46
+ puts "\n\n#{opts.map{|k,v| "#{k}:#{v}"}.join(', ')}"
47
+ puts "\nargs: #{argv.join(', ')}"
48
+ end
49
+
50
+ opts
51
+ end
52
+
53
+
54
+ def standard_opts(parser)
55
+ parser.opt :info, "Informational messages; show the major things this is doing", :short => :i, :default => true
56
+ parser.opt :quiet, "Quiet messages; only show errors", :short => :q
57
+ parser.opt :verbose, "Verbose messages; show lots of details on what this is doing", :short => :v
58
+ parser.opt :version, "Print version (#{GitProc::Version::STRING}) and exit", :short => :none
59
+ parser.opt :help, "Show this message", :short => :h
60
+
61
+ parser.conflicts :verbose, :info, :quiet
62
+ end
63
+
64
+
65
+ def summary
66
+ "Default summary"
67
+ end
68
+
69
+
70
+ def usage(filename)
71
+ "#{filename} [options]"
72
+ end
73
+
74
+
75
+ def description
76
+ "Default description"
77
+ end
78
+
79
+
80
+ def empty_argv_ok?
81
+ true
82
+ end
83
+
84
+
85
+ def extend_opts(parser)
86
+ # extension point - does nothing by default
87
+ end
88
+
89
+
90
+ # def extend_args(argv)
91
+ # # extension point - does nothing by default
92
+ # end
93
+
94
+
95
+ def post_parse(opts, argv)
96
+ # extension point - does nothing by default
97
+ end
98
+
99
+ end
100
+
101
+ end
@@ -0,0 +1,38 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
13
+ require 'git-process/git_abstract_merge_error_builder'
14
+
15
+ module GitProc
16
+
17
+ class RebaseError < GitProcessError
18
+ include GitProc::AbstractMergeErrorBuilder
19
+
20
+ attr_reader :error_message, :lib
21
+
22
+ def initialize(rebase_error_message, lib)
23
+ @lib = lib
24
+ @error_message = rebase_error_message
25
+
26
+ msg = build_message
27
+
28
+ super(msg)
29
+ end
30
+
31
+
32
+ def continue_command
33
+ 'git rebase --continue'
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -1,4 +1,16 @@
1
- module Git
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
13
+ module GitProc
2
14
 
3
15
  #
4
16
  # The status of the Git repository.
@@ -1,3 +1,15 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.require 'shellwords'
12
+
1
13
  require 'octokit'
2
14
 
3
15
  module Octokit
@@ -65,7 +77,7 @@ class GitHubClient < Octokit::Client
65
77
 
66
78
  def request(method, path, options, version, authenticate, raw, force_urlencoded)
67
79
  if /api.github.com/ !~ site
68
- path = "/api/v3#{path}"
80
+ path = "/api/v3/#{path}"
69
81
  end
70
82
  old_request(method, path, options, version, authenticate, raw, force_urlencoded)
71
83
  end