git-process 1.1.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. data/CHANGELOG.md +14 -1
  2. data/LICENSE +193 -22
  3. data/README.md +212 -71
  4. data/man/git-process.1 +371 -0
  5. metadata +52 -140
  6. data/Gemfile +0 -20
  7. data/Gemfile.lock +0 -53
  8. data/Rakefile +0 -16
  9. data/bin/git-new-fb +0 -58
  10. data/bin/git-pull-request +0 -107
  11. data/bin/git-sync +0 -73
  12. data/bin/git-to-master +0 -133
  13. data/git-process.gemspec +0 -25
  14. data/lib/git-process/abstract_error_builder.rb +0 -53
  15. data/lib/git-process/changed_file_helper.rb +0 -115
  16. data/lib/git-process/git_abstract_merge_error_builder.rb +0 -146
  17. data/lib/git-process/git_branch.rb +0 -105
  18. data/lib/git-process/git_branches.rb +0 -73
  19. data/lib/git-process/git_config.rb +0 -153
  20. data/lib/git-process/git_lib.rb +0 -512
  21. data/lib/git-process/git_logger.rb +0 -84
  22. data/lib/git-process/git_merge_error.rb +0 -28
  23. data/lib/git-process/git_process.rb +0 -172
  24. data/lib/git-process/git_process_error.rb +0 -18
  25. data/lib/git-process/git_process_options.rb +0 -99
  26. data/lib/git-process/git_rebase_error.rb +0 -30
  27. data/lib/git-process/git_remote.rb +0 -256
  28. data/lib/git-process/git_status.rb +0 -108
  29. data/lib/git-process/github_configuration.rb +0 -298
  30. data/lib/git-process/github_pull_request.rb +0 -151
  31. data/lib/git-process/new_fb.rb +0 -50
  32. data/lib/git-process/parked_changes_error.rb +0 -41
  33. data/lib/git-process/pull_request.rb +0 -134
  34. data/lib/git-process/pull_request_error.rb +0 -25
  35. data/lib/git-process/rebase_to_master.rb +0 -148
  36. data/lib/git-process/sync.rb +0 -136
  37. data/lib/git-process/uncommitted_changes_error.rb +0 -23
  38. data/lib/git-process/version.rb +0 -22
  39. data/spec/FileHelpers.rb +0 -19
  40. data/spec/GitRepoHelper.rb +0 -123
  41. data/spec/changed_file_helper_spec.rb +0 -127
  42. data/spec/git_abstract_merge_error_builder_spec.rb +0 -126
  43. data/spec/git_branch_spec.rb +0 -123
  44. data/spec/git_config_spec.rb +0 -45
  45. data/spec/git_lib_spec.rb +0 -176
  46. data/spec/git_logger_spec.rb +0 -66
  47. data/spec/git_process_spec.rb +0 -208
  48. data/spec/git_remote_spec.rb +0 -227
  49. data/spec/git_status_spec.rb +0 -122
  50. data/spec/github_configuration_spec.rb +0 -152
  51. data/spec/github_pull_request_spec.rb +0 -96
  52. data/spec/github_test_helper.rb +0 -49
  53. data/spec/new_fb_spec.rb +0 -130
  54. data/spec/pull_request_helper.rb +0 -94
  55. data/spec/pull_request_spec.rb +0 -128
  56. data/spec/rebase_to_master_spec.rb +0 -429
  57. data/spec/spec_helper.rb +0 -21
  58. data/spec/sync_spec.rb +0 -304
@@ -1,73 +0,0 @@
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.
12
-
13
- require 'set'
14
- require 'git-process/git_branch'
15
-
16
- module GitProc
17
-
18
- class GitBranches
19
- include Enumerable
20
-
21
-
22
- def initialize(lib)
23
- @lib = lib
24
- branch_lines = lib.branch(nil, :all => true, :no_color => true).split("\n")
25
- @items = SortedSet.new
26
- branch_lines.each do |bl|
27
- @items << GitBranch.new(bl[2..-1], bl[0..0] == '*', lib)
28
- end
29
- end
30
-
31
-
32
- def <<(item)
33
- @items << item
34
- end
35
-
36
-
37
- def each(&block)
38
- @items.each { |b| block.call(b) }
39
- end
40
-
41
-
42
- def names
43
- @items.map { |b| b.name }
44
- end
45
-
46
-
47
- def current
48
- @items.find { |b| b.current? }
49
- end
50
-
51
-
52
- def parking
53
- @items.find { |b| b.name == '_parking_' }
54
- end
55
-
56
-
57
- def include?(branch_name)
58
- @items.find { |b| b.name == branch_name } != nil
59
- end
60
-
61
-
62
- def [](branch_name)
63
- branch_name = current.name if branch_name == 'HEAD'
64
- br = @items.find { |b| b.name == branch_name }
65
- if br.nil? and branch_name !~ /origin\// and branch_name != '_parking_'
66
- @lib.logger.warn { "Could not find '#{branch_name}' in #{@items.map { |i| i.name }.join(',')}" }
67
- end
68
- br
69
- end
70
-
71
- end
72
-
73
- end
@@ -1,153 +0,0 @@
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.
12
-
13
- require 'git-process/git_logger'
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'
18
-
19
-
20
- class String
21
-
22
- def to_boolean
23
- return false if self == false || self.nil? || self =~ (/(false|f|no|n|0)$/i)
24
- return true if self == true || self =~ (/(true|t|yes|y|1)$/i)
25
- raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
26
- end
27
-
28
- end
29
-
30
-
31
- class NilClass
32
- def to_boolean
33
- false
34
- end
35
- end
36
-
37
-
38
- module GitProc
39
-
40
- #
41
- # Provides Git configuration
42
- #
43
- class GitConfig
44
-
45
- def initialize(lib)
46
- @lib = lib
47
- end
48
-
49
-
50
- def [](key)
51
- value = config_hash[key]
52
- unless value
53
- value = @lib.command(:config, ['--get', key])
54
- value = nil if value.empty?
55
- config_hash[key] = value unless config_hash.empty?
56
- end
57
- value
58
- end
59
-
60
-
61
- def []=(key, value)
62
- @lib.command(:config, [key, value])
63
- config_hash[key] = value unless config_hash.empty?
64
- value
65
- end
66
-
67
-
68
- def set_global(key, value)
69
- @lib.command(:config, ['--global', key, value])
70
- config_hash[key] = value unless config_hash.empty?
71
- value
72
- end
73
-
74
-
75
- def gitlib
76
- @lib
77
- end
78
-
79
-
80
- def logger
81
- gitlib.logger
82
- end
83
-
84
-
85
- def master_branch
86
- @master_branch ||= self['gitProcess.integrationBranch'] || 'master'
87
- end
88
-
89
-
90
- def remote_master_branch
91
- remote.master_branch_name
92
- end
93
-
94
-
95
- def integration_branch
96
- remote.exists? ? remote_master_branch : self.master_branch
97
- end
98
-
99
-
100
- def rerere_enabled?
101
- re = self['rerere.enabled']
102
- re && re.to_boolean
103
- end
104
-
105
-
106
- def rerere_enabled(re, global = true)
107
- if global
108
- set_global('rerere.enabled', re)
109
- else
110
- self['rerere.enabled'] = re
111
- end
112
- end
113
-
114
-
115
- def rerere_enabled=(re)
116
- rerere_enabled(re, false)
117
- end
118
-
119
-
120
- def rerere_autoupdate?
121
- re = self['rerere.autoupdate']
122
- re && re.to_boolean
123
- end
124
-
125
-
126
- def rerere_autoupdate(re, global = true)
127
- if global
128
- set_global('rerere.autoupdate', re)
129
- else
130
- self['rerere.autoupdate'] = re
131
- end
132
- end
133
-
134
-
135
- def rerere_autoupdate=(re)
136
- rerere_autoupdate(re, false)
137
- end
138
-
139
-
140
- private
141
-
142
- def remote
143
- gitlib.remote
144
- end
145
-
146
-
147
- def config_hash
148
- @config_hash ||= {}
149
- end
150
-
151
- end
152
-
153
- end
@@ -1,512 +0,0 @@
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.
12
-
13
- require 'logger'
14
- require 'git-process/git_branch'
15
- require 'git-process/git_branches'
16
- require 'git-process/git_remote'
17
- require 'git-process/git_status'
18
- require 'git-process/git_process_error'
19
-
20
-
21
- module GitProc
22
-
23
- class GitExecuteError < GitProcessError
24
- end
25
-
26
-
27
- #
28
- # Provides Git commands
29
- #
30
- #noinspection RubyTooManyMethodsInspection
31
- class GitLib
32
-
33
- # @param [Dir] dir
34
- def initialize(dir, opts)
35
- self.log_level = GitLib.log_level(opts)
36
- self.workdir = dir
37
- end
38
-
39
-
40
- def logger
41
- if @logger.nil?
42
- @logger = GitLogger.new(log_level)
43
- end
44
- @logger
45
- end
46
-
47
-
48
- def self.log_level(opts)
49
- if opts[:log_level]
50
- opts[:log_level]
51
- elsif opts[:quiet]
52
- Logger::ERROR
53
- elsif opts[:verbose]
54
- Logger::DEBUG
55
- else
56
- Logger::INFO
57
- end
58
- end
59
-
60
-
61
- def log_level
62
- @log_level || Logger::WARN
63
- end
64
-
65
-
66
- def log_level=(lvl)
67
- @log_level = lvl
68
- end
69
-
70
-
71
- def workdir
72
- @workdir
73
- end
74
-
75
-
76
- def workdir=(dir)
77
- workdir = GitLib.find_workdir(dir)
78
- if workdir.nil?
79
- @workdir = dir
80
- logger.info { "Initializing new repository at #{dir}" }
81
- command(:init)
82
- else
83
- @workdir = workdir
84
- logger.debug { "Opening existing repository at #{dir}" }
85
- end
86
- end
87
-
88
-
89
- def self.find_workdir(dir)
90
- if dir == File::SEPARATOR
91
- nil
92
- elsif File.directory?(File.join(dir, '.git'))
93
- dir
94
- else
95
- find_workdir(File.expand_path("#{dir}#{File::SEPARATOR}.."))
96
- end
97
- end
98
-
99
-
100
- def config
101
- if @config.nil?
102
- @config = GitConfig.new(self)
103
- end
104
- @config
105
- end
106
-
107
-
108
- def remote
109
- if @remote.nil?
110
- @remote = GitProc::GitRemote.new(config)
111
- end
112
- @remote
113
- end
114
-
115
-
116
- # @return [Boolean] does this have a remote defined?
117
- def has_a_remote?
118
- remote.exists?
119
- end
120
-
121
-
122
- def add(file)
123
- logger.info { "Adding #{[*file].join(', ')}" }
124
- command(:add, ['--', file])
125
- end
126
-
127
-
128
- def commit(msg = nil)
129
- logger.info 'Committing changes'
130
- command(:commit, msg.nil? ? nil : ['-m', msg])
131
- end
132
-
133
-
134
- def rebase(base, opts = {})
135
- args = []
136
- if opts[:interactive]
137
- logger.info { "Interactively rebasing #{branches.current.name} against #{base}" }
138
- args << '-i'
139
- else
140
- logger.info { "Rebasing #{branches.current.name} against #{base}" }
141
- end
142
- args << base
143
- command('rebase', args)
144
- end
145
-
146
-
147
- def merge(base)
148
- logger.info { "Merging #{branches.current.name} with #{base}" }
149
- command(:merge, [base])
150
- end
151
-
152
-
153
- def fetch(name = remote.name)
154
- logger.info 'Fetching the latest changes from the server'
155
- output = self.command(:fetch, ['-p', name])
156
-
157
- log_fetch_changes(fetch_changes(output))
158
-
159
- output
160
- end
161
-
162
-
163
- # @param [Hash] changes a hash of the changes that were made
164
- #
165
- # @return [void]
166
- def log_fetch_changes(changes)
167
- changes.each do |key, v|
168
- unless v.empty?
169
- logger.info { " #{key.to_s.sub(/_/, ' ')}: #{v.join(', ')}" }
170
- end
171
- end
172
- end
173
-
174
-
175
- # @return [Hash]
176
- def fetch_changes(output)
177
- changed = output.split("\n")
178
-
179
- changes = {:new_branch => [], :new_tag => [], :force_updated => [], :deleted => [], :updated => []}
180
-
181
- line = changed.shift
182
-
183
- until line.nil? do
184
- case line
185
- when /^\s\s\s/
186
- m = /^\s\s\s(\S+)\s+(\S+)\s/.match(line)
187
- changes[:updated] << "#{m[2]} (#{m[1]})"
188
- when /^\s\*\s\[new branch\]/
189
- m = /^\s\*\s\[new branch\]\s+(\S+)\s/.match(line)
190
- changes[:new_branch] << m[1]
191
- when /^\s\*\s\[new tag\]/
192
- m = /^\s\*\s\[new tag\]\s+(\S+)\s/.match(line)
193
- changes[:new_tag] << m[1]
194
- when /^\sx\s/
195
- m = /^\sx\s\[deleted\]\s+\(none\)\s+->\s+[^\/]+\/(\S+)/.match(line)
196
- changes[:deleted] << m[1]
197
- when /^\s\+\s/
198
- m = /^\s\+\s(\S+)\s+(\S+)\s/.match(line)
199
- changes[:force_updated] << "#{m[2]} (#{m[1]})"
200
- else
201
- # ignore the line
202
- end
203
- line = changed.shift
204
- end
205
-
206
- changes
207
- end
208
-
209
-
210
- def branches
211
- GitProc::GitBranches.new(self)
212
- end
213
-
214
-
215
- #
216
- # Does branch manipulation.
217
- #
218
- # @param [String] branch_name the name of the branch
219
- #
220
- # @option opts [Boolean] :delete delete the remote branch
221
- # @option opts [Boolean] :force force the update
222
- # @option opts [Boolean] :all list all branches, local and remote
223
- # @option opts [Boolean] :no_color force not using any ANSI color codes
224
- # @option opts [String] :rename the new name for the branch
225
- # @option opts [String] :upstream the new branch to track
226
- # @option opts [String] :base_branch the branch to base the new branch off of;
227
- # defaults to 'master'
228
- #
229
- # @return [String] the output of running the git command
230
- def branch(branch_name, opts = {})
231
- if opts[:delete]
232
- delete_branch(branch_name, opts[:force])
233
- elsif opts[:rename]
234
- rename_branch(branch_name, opts[:rename])
235
- elsif opts[:upstream]
236
- set_upstream_branch(branch_name, opts[:upstream])
237
- elsif branch_name
238
- if opts[:force]
239
- change_branch(branch_name, opts[:base_branch])
240
- else
241
- create_branch(branch_name, opts[:base_branch])
242
- end
243
- else
244
- list_branches(opts[:all], opts[:no_color])
245
- end
246
- end
247
-
248
-
249
- #
250
- # Pushes the given branch to the server.
251
- #
252
- # @param [String] remote_name the repository name; nil -> 'origin'
253
- # @param [String] local_branch the local branch to push; nil -> the current branch
254
- # @param [String] remote_branch the name of the branch to push to; nil -> same as local_branch
255
- #
256
- # @option opts [Boolean, String] :delete delete the remote branch
257
- # @option opts [Boolean] :force force the update, even if not a fast-forward
258
- #
259
- # @return [void]
260
- #
261
- # @raise [ArgumentError] if :delete is true, but no branch name is given
262
- def push(remote_name, local_branch, remote_branch, opts = {})
263
- remote_name ||= 'origin'
264
-
265
- args = [remote_name]
266
-
267
- if opts[:delete]
268
- if remote_branch
269
- rb = remote_branch
270
- elsif local_branch
271
- rb = local_branch
272
- elsif !(opts[:delete].is_a? TrueClass)
273
- rb = opts[:delete]
274
- else
275
- raise ArgumentError.new('Need a branch name to delete.')
276
- end
277
-
278
- int_branch = config.master_branch
279
- if rb == int_branch
280
- raise GitProc::GitProcessError.new("Can not delete the integration branch '#{int_branch}'")
281
- end
282
-
283
- logger.info { "Deleting remote branch '#{rb}' on '#{remote_name}'." }
284
- args << '--delete' << rb
285
- else
286
- local_branch ||= branches.current
287
- remote_branch ||= local_branch
288
- args << '-f' if opts[:force]
289
-
290
- logger.info do
291
- if local_branch == remote_branch
292
- "Pushing to '#{remote_branch}' on '#{remote_name}'."
293
- else
294
- "Pushing #{local_branch} to '#{remote_branch}' on '#{remote_name}'."
295
- end
296
- end
297
-
298
- args << "#{local_branch}:#{remote_branch}"
299
- end
300
- command(:push, args)
301
- end
302
-
303
-
304
- def rebase_continue
305
- command(:rebase, '--continue')
306
- end
307
-
308
-
309
- def stash_save
310
- command(:stash, %w(save))
311
- end
312
-
313
-
314
- def stash_pop
315
- command(:stash, %w(pop))
316
- end
317
-
318
-
319
- def show(refspec)
320
- command(:show, refspec)
321
- end
322
-
323
-
324
- def checkout(branch_name, opts = {})
325
- args = []
326
- args << '--no-track' if opts[:no_track]
327
- args << '-b' if opts[:new_branch]
328
- args << branch_name
329
- args << opts[:new_branch] if opts[:new_branch]
330
- branches = branches()
331
- command(:checkout, args)
332
-
333
- branches << GitBranch.new(branch_name, opts[:new_branch] != nil, self)
334
-
335
- if block_given?
336
- yield
337
- command(:checkout, branches.current.name)
338
- branches.current
339
- else
340
- branches[branch_name]
341
- end
342
- end
343
-
344
-
345
- def log_count
346
- command(:log, '--oneline').split(/\n/).length
347
- end
348
-
349
-
350
- def remove(files, opts = {})
351
- args = []
352
- args << '-f' if opts[:force]
353
- args << [*files]
354
- command(:rm, args)
355
- end
356
-
357
-
358
- #
359
- # Returns the status of the git repository.
360
- #
361
- # @return [Status]
362
- def status
363
- GitStatus.new(self)
364
- end
365
-
366
-
367
- # @return [String] the raw porcelain status string
368
- def porcelain_status
369
- command(:status, '--porcelain')
370
- end
371
-
372
-
373
- def reset(rev_name, opts = {})
374
- args = []
375
- args << '--hard' if opts[:hard]
376
- args << rev_name
377
-
378
- logger.info { "Resetting #{opts[:hard] ? '(hard)' : ''} to #{rev_name}" }
379
-
380
- command(:reset, args)
381
- end
382
-
383
-
384
- def rev_list(start_revision, end_revision, opts ={})
385
- args = []
386
- args << "-#{opts[:num_revs]}" if opts[:num_revs]
387
- args << '--oneline' if opts[:oneline]
388
- args << "#{start_revision}..#{end_revision}"
389
- command('rev-list', args)
390
- end
391
-
392
-
393
- def rev_parse(name)
394
- command('rev-parse', name)
395
- end
396
-
397
-
398
- alias sha rev_parse
399
-
400
-
401
- # @return [String]
402
- def command(cmd, opts = [], chdir = true, redirect = '', &block)
403
- ENV['GIT_INDEX_FILE'] = File.join(workdir, '.git', 'index')
404
- ENV['GIT_DIR'] = File.join(workdir, '.git')
405
- ENV['GIT_WORK_TREE'] = workdir
406
- path = workdir
407
-
408
- git_cmd = create_git_command(cmd, opts, redirect)
409
-
410
- out = command_git_cmd(path, git_cmd, chdir, block)
411
-
412
- if logger
413
- logger.debug(git_cmd)
414
- logger.debug(out)
415
- end
416
-
417
- handle_exitstatus($?, git_cmd, out)
418
- end
419
-
420
-
421
- private
422
-
423
-
424
- def create_git_command(cmd, opts, redirect)
425
- opts = [opts].flatten.map { |s| escape(s) }.join(' ')
426
- "git #{cmd} #{opts} #{redirect} 2>&1"
427
- end
428
-
429
-
430
- def command_git_cmd(path, git_cmd, chdir, block)
431
- out = nil
432
- if chdir and (Dir.getwd != path)
433
- Dir.chdir(path) { out = run_command(git_cmd, &block) }
434
- else
435
- out = run_command(git_cmd, &block)
436
- end
437
- out
438
- end
439
-
440
-
441
- # @return [String]
442
- def handle_exitstatus(proc_status, git_cmd, out)
443
- if proc_status.exitstatus > 0
444
- unless proc_status.exitstatus == 1 && out == ''
445
- raise GitProc::GitExecuteError.new(git_cmd + ':' + out.to_s)
446
- end
447
- end
448
- out
449
- end
450
-
451
-
452
- def run_command(git_cmd, &block)
453
- if block_given?
454
- IO.popen(git_cmd, &block)
455
- else
456
- `#{git_cmd}`.chomp
457
- end
458
- end
459
-
460
-
461
- def escape(s)
462
- escaped = s.to_s.gsub('\'', '\'\\\'\'')
463
- %Q{"#{escaped}"}
464
- end
465
-
466
-
467
- def change_branch(branch_name, base_branch)
468
- raise ArgumentError.new('Need :base_branch when using :force for a branch.') unless base_branch
469
- logger.info { "Changing branch '#{branch_name}' to point to '#{base_branch}'." }
470
-
471
- command(:branch, ['-f', branch_name, base_branch])
472
- end
473
-
474
-
475
- def create_branch(branch_name, base_branch)
476
- logger.info { "Creating new branch '#{branch_name}' based on '#{base_branch}'." }
477
-
478
- command(:branch, [branch_name, (base_branch || 'master')])
479
- end
480
-
481
-
482
- def list_branches(all_branches, no_color)
483
- args = []
484
- args << '-a' if all_branches
485
- args << '--no-color' if no_color
486
- command(:branch, args)
487
- end
488
-
489
-
490
- def delete_branch(branch_name, force)
491
- logger.info { "Deleting local branch '#{branch_name}'." } unless branch_name == '_parking_'
492
-
493
- command(:branch, [force ? '-D' : '-d', branch_name])
494
- end
495
-
496
-
497
- def rename_branch(branch_name, new_name)
498
- logger.info { "Renaming branch '#{branch_name}' to '#{new_name}'." }
499
-
500
- command(:branch, ['-m', branch_name, new_name])
501
- end
502
-
503
-
504
- def set_upstream_branch(branch_name, upstream)
505
- logger.info { "Setting upstream/tracking for branch '#{branch_name}' to '#{upstream}'." }
506
-
507
- command(:branch, ['--set-upstream-to', upstream, branch_name])
508
- end
509
-
510
- end
511
-
512
- end